blob: 355e01f8599e8f7d91e1148a5624bc0f2a52501d [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000124/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000125/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000126#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000127#include <process.h>
128#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000129#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#define HAVE_GETCWD 1
131#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000132#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000133#if defined(__OS2__)
134#define HAVE_EXECV 1
135#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000136#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#include <process.h>
138#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000139#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#define HAVE_EXECV 1
141#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#define HAVE_OPENDIR 1
143#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#define HAVE_WAIT 1
146#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000147#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000148#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000149#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000150#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000152#define HAVE_EXECV 1
153#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#define HAVE_SYSTEM 1
155#define HAVE_CWAIT 1
156#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000157#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000158#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000159#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
160/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162/* Unix functions that the configure script doesn't check for */
163#define HAVE_EXECV 1
164#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000166#define HAVE_FORK1 1
167#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_GETCWD 1
169#define HAVE_GETEGID 1
170#define HAVE_GETEUID 1
171#define HAVE_GETGID 1
172#define HAVE_GETPPID 1
173#define HAVE_GETUID 1
174#define HAVE_KILL 1
175#define HAVE_OPENDIR 1
176#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000177#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000179#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000180#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#endif /* _MSC_VER */
182#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000183#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000184#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000185
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000186#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000187
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000188#if defined(__sgi)&&_COMPILER_VERSION>=700
189/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
190 (default) */
191extern char *ctermid_r(char *);
192#endif
193
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000194#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000195#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000197#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000198#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000199extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000200#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000201extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000202#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000203#endif
204#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000205extern int chdir(char *);
206extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000207#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int chdir(const char *);
209extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000211#ifdef __BORLANDC__
212extern int chmod(const char *, int);
213#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000214extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000215#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000216/*#ifdef HAVE_FCHMOD
217extern int fchmod(int, mode_t);
218#endif*/
219/*#ifdef HAVE_LCHMOD
220extern int lchmod(const char *, mode_t);
221#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int chown(const char *, uid_t, gid_t);
223extern char *getcwd(char *, int);
224extern char *strerror(int);
225extern int link(const char *, const char *);
226extern int rename(const char *, const char *);
227extern int stat(const char *, struct stat *);
228extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000230extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000231#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000233extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000234#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000236
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000237#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#ifdef HAVE_UTIME_H
240#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000241#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000243#ifdef HAVE_SYS_UTIME_H
244#include <sys/utime.h>
245#define HAVE_UTIME_H /* pretend we do for the rest of this file */
246#endif /* HAVE_SYS_UTIME_H */
247
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#ifdef HAVE_SYS_TIMES_H
249#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000250#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251
252#ifdef HAVE_SYS_PARAM_H
253#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000254#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255
256#ifdef HAVE_SYS_UTSNAME_H
257#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000258#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000260#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000262#define NAMLEN(dirent) strlen((dirent)->d_name)
263#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000264#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000265#include <direct.h>
266#define NAMLEN(dirent) strlen((dirent)->d_name)
267#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000270#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000271#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000273#endif
274#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#endif
277#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#endif
280#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000283#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000285#endif
286#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288#endif
289#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000291#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000292#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000293#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000294#endif
295#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000296#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000297#endif
298#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000299#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000300#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000301#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000302#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000303#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000304#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000305#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000306#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
307#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000308static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000309#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000310#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000311
Guido van Rossumd48f2521997-12-05 22:19:34 +0000312#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000314#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000317#if defined(PATH_MAX) && PATH_MAX > 1024
318#define MAXPATHLEN PATH_MAX
319#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000320#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000321#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000322#endif /* MAXPATHLEN */
323
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000324#ifdef UNION_WAIT
325/* Emulate some macros on systems that have a union instead of macros */
326
327#ifndef WIFEXITED
328#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
329#endif
330
331#ifndef WEXITSTATUS
332#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
333#endif
334
335#ifndef WTERMSIG
336#define WTERMSIG(u_wait) ((u_wait).w_termsig)
337#endif
338
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000339#define WAIT_TYPE union wait
340#define WAIT_STATUS_INT(s) (s.w_status)
341
342#else /* !UNION_WAIT */
343#define WAIT_TYPE int
344#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000345#endif /* UNION_WAIT */
346
Greg Wardb48bc172000-03-01 21:51:56 +0000347/* Don't use the "_r" form if we don't need it (also, won't have a
348 prototype for it, at least on Solaris -- maybe others as well?). */
349#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
350#define USE_CTERMID_R
351#endif
352
Fred Drake699f3522000-06-29 21:12:41 +0000353/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000354#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000355#undef FSTAT
356#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000357#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000358# define STAT win32_stat
359# define FSTAT win32_fstat
360# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000361#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000362# define STAT stat
363# define FSTAT fstat
364# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000365#endif
366
Tim Peters11b23062003-04-23 02:39:17 +0000367#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000368#include <sys/mkdev.h>
369#else
370#if defined(MAJOR_IN_SYSMACROS)
371#include <sys/sysmacros.h>
372#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000373#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
374#include <sys/mkdev.h>
375#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000376#endif
Fred Drake699f3522000-06-29 21:12:41 +0000377
Georg Brandla391b112011-02-25 15:23:18 +0000378static int
379_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000380{
381#if !defined(HAVE_LARGEFILE_SUPPORT)
382 *((off_t*)addr) = PyLong_AsLong(arg);
383#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000384 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000385#endif
386 if (PyErr_Occurred())
387 return 0;
388 return 1;
389}
390
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000391#if defined _MSC_VER && _MSC_VER >= 1400
392/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
393 * valid and throw an assertion if it isn't.
394 * Normally, an invalid fd is likely to be a C program error and therefore
395 * an assertion can be useful, but it does contradict the POSIX standard
396 * which for write(2) states:
397 * "Otherwise, -1 shall be returned and errno set to indicate the error."
398 * "[EBADF] The fildes argument is not a valid file descriptor open for
399 * writing."
400 * Furthermore, python allows the user to enter any old integer
401 * as a fd and should merely raise a python exception on error.
402 * The Microsoft CRT doesn't provide an official way to check for the
403 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000404 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000405 * internal structures involved.
406 * The structures below must be updated for each version of visual studio
407 * according to the file internal.h in the CRT source, until MS comes
408 * up with a less hacky way to do this.
409 * (all of this is to avoid globally modifying the CRT behaviour using
410 * _set_invalid_parameter_handler() and _CrtSetReportMode())
411 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000412/* The actual size of the structure is determined at runtime.
413 * Only the first items must be present.
414 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000415typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000416 intptr_t osfhnd;
417 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000418} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000419
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000420extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000421#define IOINFO_L2E 5
422#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
423#define IOINFO_ARRAYS 64
424#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
425#define FOPEN 0x01
426#define _NO_CONSOLE_FILENO (intptr_t)-2
427
428/* This function emulates what the windows CRT does to validate file handles */
429int
430_PyVerify_fd(int fd)
431{
Victor Stinner8c62be82010-05-06 00:08:46 +0000432 const int i1 = fd >> IOINFO_L2E;
433 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000434
Antoine Pitrou22e41552010-08-15 18:07:50 +0000435 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000436
Victor Stinner8c62be82010-05-06 00:08:46 +0000437 /* Determine the actual size of the ioinfo structure,
438 * as used by the CRT loaded in memory
439 */
440 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
441 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
442 }
443 if (sizeof_ioinfo == 0) {
444 /* This should not happen... */
445 goto fail;
446 }
447
448 /* See that it isn't a special CLEAR fileno */
449 if (fd != _NO_CONSOLE_FILENO) {
450 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
451 * we check pointer validity and other info
452 */
453 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
454 /* finally, check that the file is open */
455 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
456 if (info->osfile & FOPEN) {
457 return 1;
458 }
459 }
460 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000461 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000462 errno = EBADF;
463 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000464}
465
466/* the special case of checking dup2. The target fd must be in a sensible range */
467static int
468_PyVerify_fd_dup2(int fd1, int fd2)
469{
Victor Stinner8c62be82010-05-06 00:08:46 +0000470 if (!_PyVerify_fd(fd1))
471 return 0;
472 if (fd2 == _NO_CONSOLE_FILENO)
473 return 0;
474 if ((unsigned)fd2 < _NHANDLE_)
475 return 1;
476 else
477 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000478}
479#else
480/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
481#define _PyVerify_fd_dup2(A, B) (1)
482#endif
483
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000484#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000485/* The following structure was copied from
486 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
487 include doesn't seem to be present in the Windows SDK (at least as included
488 with Visual Studio Express). */
489typedef struct _REPARSE_DATA_BUFFER {
490 ULONG ReparseTag;
491 USHORT ReparseDataLength;
492 USHORT Reserved;
493 union {
494 struct {
495 USHORT SubstituteNameOffset;
496 USHORT SubstituteNameLength;
497 USHORT PrintNameOffset;
498 USHORT PrintNameLength;
499 ULONG Flags;
500 WCHAR PathBuffer[1];
501 } SymbolicLinkReparseBuffer;
502
503 struct {
504 USHORT SubstituteNameOffset;
505 USHORT SubstituteNameLength;
506 USHORT PrintNameOffset;
507 USHORT PrintNameLength;
508 WCHAR PathBuffer[1];
509 } MountPointReparseBuffer;
510
511 struct {
512 UCHAR DataBuffer[1];
513 } GenericReparseBuffer;
514 };
515} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
516
517#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
518 GenericReparseBuffer)
519#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
520
521static int
Brian Curtind25aef52011-06-13 15:16:04 -0500522win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000523{
524 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
525 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
526 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000527
528 if (0 == DeviceIoControl(
529 reparse_point_handle,
530 FSCTL_GET_REPARSE_POINT,
531 NULL, 0, /* in buffer */
532 target_buffer, sizeof(target_buffer),
533 &n_bytes_returned,
534 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500535 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000536
537 if (reparse_tag)
538 *reparse_tag = rdb->ReparseTag;
539
Brian Curtind25aef52011-06-13 15:16:04 -0500540 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000541}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000542#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000543
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000544/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000545#ifdef WITH_NEXT_FRAMEWORK
546/* On Darwin/MacOSX a shared library or framework has no access to
547** environ directly, we must obtain it with _NSGetEnviron().
548*/
549#include <crt_externs.h>
550static char **environ;
551#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000552extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000553#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000554
Barry Warsaw53699e91996-12-10 23:23:01 +0000555static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000556convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000557{
Victor Stinner8c62be82010-05-06 00:08:46 +0000558 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000559#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000560 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000561#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000562 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000563#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000564#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000565 APIRET rc;
566 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
567#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000568
Victor Stinner8c62be82010-05-06 00:08:46 +0000569 d = PyDict_New();
570 if (d == NULL)
571 return NULL;
572#ifdef WITH_NEXT_FRAMEWORK
573 if (environ == NULL)
574 environ = *_NSGetEnviron();
575#endif
576#ifdef MS_WINDOWS
577 /* _wenviron must be initialized in this way if the program is started
578 through main() instead of wmain(). */
579 _wgetenv(L"");
580 if (_wenviron == NULL)
581 return d;
582 /* This part ignores errors */
583 for (e = _wenviron; *e != NULL; e++) {
584 PyObject *k;
585 PyObject *v;
586 wchar_t *p = wcschr(*e, L'=');
587 if (p == NULL)
588 continue;
589 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
590 if (k == NULL) {
591 PyErr_Clear();
592 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000593 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000594 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
595 if (v == NULL) {
596 PyErr_Clear();
597 Py_DECREF(k);
598 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000599 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000600 if (PyDict_GetItem(d, k) == NULL) {
601 if (PyDict_SetItem(d, k, v) != 0)
602 PyErr_Clear();
603 }
604 Py_DECREF(k);
605 Py_DECREF(v);
606 }
607#else
608 if (environ == NULL)
609 return d;
610 /* This part ignores errors */
611 for (e = environ; *e != NULL; e++) {
612 PyObject *k;
613 PyObject *v;
614 char *p = strchr(*e, '=');
615 if (p == NULL)
616 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000617 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000618 if (k == NULL) {
619 PyErr_Clear();
620 continue;
621 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000622 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000623 if (v == NULL) {
624 PyErr_Clear();
625 Py_DECREF(k);
626 continue;
627 }
628 if (PyDict_GetItem(d, k) == NULL) {
629 if (PyDict_SetItem(d, k, v) != 0)
630 PyErr_Clear();
631 }
632 Py_DECREF(k);
633 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000634 }
635#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000636#if defined(PYOS_OS2)
637 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
638 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
639 PyObject *v = PyBytes_FromString(buffer);
640 PyDict_SetItemString(d, "BEGINLIBPATH", v);
641 Py_DECREF(v);
642 }
643 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
644 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
645 PyObject *v = PyBytes_FromString(buffer);
646 PyDict_SetItemString(d, "ENDLIBPATH", v);
647 Py_DECREF(v);
648 }
649#endif
650 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000651}
652
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000653/* Set a POSIX-specific error from errno, and return NULL */
654
Barry Warsawd58d7641998-07-23 16:14:40 +0000655static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000656posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000657{
Victor Stinner8c62be82010-05-06 00:08:46 +0000658 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000659}
Barry Warsawd58d7641998-07-23 16:14:40 +0000660static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000661posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000662{
Victor Stinner8c62be82010-05-06 00:08:46 +0000663 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000664}
665
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000666
Mark Hammondef8b6542001-05-13 08:04:26 +0000667static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000668posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000669{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000670 PyObject *name_str, *rc;
671 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
672 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000673 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000674 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
675 name_str);
676 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000677 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000678}
679
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000680#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000681static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000682win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000683{
Victor Stinner8c62be82010-05-06 00:08:46 +0000684 /* XXX We should pass the function name along in the future.
685 (winreg.c also wants to pass the function name.)
686 This would however require an additional param to the
687 Windows error object, which is non-trivial.
688 */
689 errno = GetLastError();
690 if (filename)
691 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
692 else
693 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000694}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000695
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000696static PyObject *
697win32_error_unicode(char* function, Py_UNICODE* filename)
698{
Victor Stinner8c62be82010-05-06 00:08:46 +0000699 /* XXX - see win32_error for comments on 'function' */
700 errno = GetLastError();
701 if (filename)
702 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
703 else
704 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000705}
706
Thomas Wouters477c8d52006-05-27 19:21:47 +0000707static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000708convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000709{
Victor Stinner8c62be82010-05-06 00:08:46 +0000710 if (PyUnicode_CheckExact(*param))
711 Py_INCREF(*param);
712 else if (PyUnicode_Check(*param))
713 /* For a Unicode subtype that's not a Unicode object,
714 return a true Unicode object with the same data. */
715 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
716 PyUnicode_GET_SIZE(*param));
717 else
718 *param = PyUnicode_FromEncodedObject(*param,
719 Py_FileSystemDefaultEncoding,
720 "strict");
721 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000722}
723
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000724#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725
Guido van Rossumd48f2521997-12-05 22:19:34 +0000726#if defined(PYOS_OS2)
727/**********************************************************************
728 * Helper Function to Trim and Format OS/2 Messages
729 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000730static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000731os2_formatmsg(char *msgbuf, int msglen, char *reason)
732{
733 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
734
735 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
736 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
737
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000738 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000739 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
740 }
741
742 /* Add Optional Reason Text */
743 if (reason) {
744 strcat(msgbuf, " : ");
745 strcat(msgbuf, reason);
746 }
747}
748
749/**********************************************************************
750 * Decode an OS/2 Operating System Error Code
751 *
752 * A convenience function to lookup an OS/2 error code and return a
753 * text message we can use to raise a Python exception.
754 *
755 * Notes:
756 * The messages for errors returned from the OS/2 kernel reside in
757 * the file OSO001.MSG in the \OS2 directory hierarchy.
758 *
759 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000760static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000761os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
762{
763 APIRET rc;
764 ULONG msglen;
765
766 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
767 Py_BEGIN_ALLOW_THREADS
768 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
769 errorcode, "oso001.msg", &msglen);
770 Py_END_ALLOW_THREADS
771
772 if (rc == NO_ERROR)
773 os2_formatmsg(msgbuf, msglen, reason);
774 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000775 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000776 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000777
778 return msgbuf;
779}
780
781/* Set an OS/2-specific error and return NULL. OS/2 kernel
782 errors are not in a global variable e.g. 'errno' nor are
783 they congruent with posix error numbers. */
784
Victor Stinner8c62be82010-05-06 00:08:46 +0000785static PyObject *
786os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000787{
788 char text[1024];
789 PyObject *v;
790
791 os2_strerror(text, sizeof(text), code, "");
792
793 v = Py_BuildValue("(is)", code, text);
794 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000795 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000796 Py_DECREF(v);
797 }
798 return NULL; /* Signal to Python that an Exception is Pending */
799}
800
801#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000802
803/* POSIX generic methods */
804
Barry Warsaw53699e91996-12-10 23:23:01 +0000805static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000806posix_fildes(PyObject *fdobj, int (*func)(int))
807{
Victor Stinner8c62be82010-05-06 00:08:46 +0000808 int fd;
809 int res;
810 fd = PyObject_AsFileDescriptor(fdobj);
811 if (fd < 0)
812 return NULL;
813 if (!_PyVerify_fd(fd))
814 return posix_error();
815 Py_BEGIN_ALLOW_THREADS
816 res = (*func)(fd);
817 Py_END_ALLOW_THREADS
818 if (res < 0)
819 return posix_error();
820 Py_INCREF(Py_None);
821 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000822}
Guido van Rossum21142a01999-01-08 21:05:37 +0000823
824static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000825posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000826{
Victor Stinner8c62be82010-05-06 00:08:46 +0000827 PyObject *opath1 = NULL;
828 char *path1;
829 int res;
830 if (!PyArg_ParseTuple(args, format,
831 PyUnicode_FSConverter, &opath1))
832 return NULL;
833 path1 = PyBytes_AsString(opath1);
834 Py_BEGIN_ALLOW_THREADS
835 res = (*func)(path1);
836 Py_END_ALLOW_THREADS
837 if (res < 0)
838 return posix_error_with_allocated_filename(opath1);
839 Py_DECREF(opath1);
840 Py_INCREF(Py_None);
841 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000842}
843
Barry Warsaw53699e91996-12-10 23:23:01 +0000844static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000845posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000846 char *format,
847 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000848{
Victor Stinner8c62be82010-05-06 00:08:46 +0000849 PyObject *opath1 = NULL, *opath2 = NULL;
850 char *path1, *path2;
851 int res;
852 if (!PyArg_ParseTuple(args, format,
853 PyUnicode_FSConverter, &opath1,
854 PyUnicode_FSConverter, &opath2)) {
855 return NULL;
856 }
857 path1 = PyBytes_AsString(opath1);
858 path2 = PyBytes_AsString(opath2);
859 Py_BEGIN_ALLOW_THREADS
860 res = (*func)(path1, path2);
861 Py_END_ALLOW_THREADS
862 Py_DECREF(opath1);
863 Py_DECREF(opath2);
864 if (res != 0)
865 /* XXX how to report both path1 and path2??? */
866 return posix_error();
867 Py_INCREF(Py_None);
868 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000869}
870
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000871#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000872static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000873win32_1str(PyObject* args, char* func,
874 char* format, BOOL (__stdcall *funcA)(LPCSTR),
875 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000876{
Victor Stinner8c62be82010-05-06 00:08:46 +0000877 PyObject *uni;
878 char *ansi;
879 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000880
Victor Stinner8c62be82010-05-06 00:08:46 +0000881 if (!PyArg_ParseTuple(args, wformat, &uni))
882 PyErr_Clear();
883 else {
884 Py_BEGIN_ALLOW_THREADS
885 result = funcW(PyUnicode_AsUnicode(uni));
886 Py_END_ALLOW_THREADS
887 if (!result)
888 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
889 Py_INCREF(Py_None);
890 return Py_None;
891 }
892 if (!PyArg_ParseTuple(args, format, &ansi))
893 return NULL;
894 Py_BEGIN_ALLOW_THREADS
895 result = funcA(ansi);
896 Py_END_ALLOW_THREADS
897 if (!result)
898 return win32_error(func, ansi);
899 Py_INCREF(Py_None);
900 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000901
902}
903
904/* This is a reimplementation of the C library's chdir function,
905 but one that produces Win32 errors instead of DOS error codes.
906 chdir is essentially a wrapper around SetCurrentDirectory; however,
907 it also needs to set "magic" environment variables indicating
908 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000909static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000910win32_chdir(LPCSTR path)
911{
Victor Stinner8c62be82010-05-06 00:08:46 +0000912 char new_path[MAX_PATH+1];
913 int result;
914 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000915
Victor Stinner8c62be82010-05-06 00:08:46 +0000916 if(!SetCurrentDirectoryA(path))
917 return FALSE;
918 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
919 if (!result)
920 return FALSE;
921 /* In the ANSI API, there should not be any paths longer
922 than MAX_PATH. */
923 assert(result <= MAX_PATH+1);
924 if (strncmp(new_path, "\\\\", 2) == 0 ||
925 strncmp(new_path, "//", 2) == 0)
926 /* UNC path, nothing to do. */
927 return TRUE;
928 env[1] = new_path[0];
929 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000930}
931
932/* The Unicode version differs from the ANSI version
933 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000934static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000935win32_wchdir(LPCWSTR path)
936{
Victor Stinner8c62be82010-05-06 00:08:46 +0000937 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
938 int result;
939 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000940
Victor Stinner8c62be82010-05-06 00:08:46 +0000941 if(!SetCurrentDirectoryW(path))
942 return FALSE;
943 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
944 if (!result)
945 return FALSE;
946 if (result > MAX_PATH+1) {
947 new_path = malloc(result * sizeof(wchar_t));
948 if (!new_path) {
949 SetLastError(ERROR_OUTOFMEMORY);
950 return FALSE;
951 }
952 result = GetCurrentDirectoryW(result, new_path);
953 if (!result) {
954 free(new_path);
955 return FALSE;
956 }
957 }
958 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
959 wcsncmp(new_path, L"//", 2) == 0)
960 /* UNC path, nothing to do. */
961 return TRUE;
962 env[1] = new_path[0];
963 result = SetEnvironmentVariableW(env, new_path);
964 if (new_path != _new_path)
965 free(new_path);
966 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000967}
968#endif
969
Martin v. Löwis14694662006-02-03 12:54:16 +0000970#ifdef MS_WINDOWS
971/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
972 - time stamps are restricted to second resolution
973 - file modification times suffer from forth-and-back conversions between
974 UTC and local time
975 Therefore, we implement our own stat, based on the Win32 API directly.
976*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000977#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000978
979struct win32_stat{
980 int st_dev;
981 __int64 st_ino;
982 unsigned short st_mode;
983 int st_nlink;
984 int st_uid;
985 int st_gid;
986 int st_rdev;
987 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000988 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000989 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000990 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000991 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000992 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000993 int st_ctime_nsec;
994};
995
996static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
997
998static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +0000999FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001000{
Victor Stinner8c62be82010-05-06 00:08:46 +00001001 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1002 /* Cannot simply cast and dereference in_ptr,
1003 since it might not be aligned properly */
1004 __int64 in;
1005 memcpy(&in, in_ptr, sizeof(in));
1006 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001007 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001008}
1009
Thomas Wouters477c8d52006-05-27 19:21:47 +00001010static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001011time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001012{
Victor Stinner8c62be82010-05-06 00:08:46 +00001013 /* XXX endianness */
1014 __int64 out;
1015 out = time_in + secs_between_epochs;
1016 out = out * 10000000 + nsec_in / 100;
1017 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001018}
1019
Martin v. Löwis14694662006-02-03 12:54:16 +00001020/* Below, we *know* that ugo+r is 0444 */
1021#if _S_IREAD != 0400
1022#error Unsupported C library
1023#endif
1024static int
1025attributes_to_mode(DWORD attr)
1026{
Victor Stinner8c62be82010-05-06 00:08:46 +00001027 int m = 0;
1028 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1029 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1030 else
1031 m |= _S_IFREG;
1032 if (attr & FILE_ATTRIBUTE_READONLY)
1033 m |= 0444;
1034 else
1035 m |= 0666;
1036 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001037}
1038
1039static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001040attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001041{
Victor Stinner8c62be82010-05-06 00:08:46 +00001042 memset(result, 0, sizeof(*result));
1043 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1044 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1045 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1046 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1047 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001048 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001049 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001050 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1051 /* first clear the S_IFMT bits */
1052 result->st_mode ^= (result->st_mode & 0170000);
1053 /* now set the bits that make this a symlink */
1054 result->st_mode |= 0120000;
1055 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001056
Victor Stinner8c62be82010-05-06 00:08:46 +00001057 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001058}
1059
Guido van Rossumd8faa362007-04-27 19:54:29 +00001060static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001061attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001062{
Victor Stinner8c62be82010-05-06 00:08:46 +00001063 HANDLE hFindFile;
1064 WIN32_FIND_DATAA FileData;
1065 hFindFile = FindFirstFileA(pszFile, &FileData);
1066 if (hFindFile == INVALID_HANDLE_VALUE)
1067 return FALSE;
1068 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001069 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001070 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001071 info->dwFileAttributes = FileData.dwFileAttributes;
1072 info->ftCreationTime = FileData.ftCreationTime;
1073 info->ftLastAccessTime = FileData.ftLastAccessTime;
1074 info->ftLastWriteTime = FileData.ftLastWriteTime;
1075 info->nFileSizeHigh = FileData.nFileSizeHigh;
1076 info->nFileSizeLow = FileData.nFileSizeLow;
1077/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001078 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1079 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001080 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001081}
1082
1083static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001084attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001085{
Victor Stinner8c62be82010-05-06 00:08:46 +00001086 HANDLE hFindFile;
1087 WIN32_FIND_DATAW FileData;
1088 hFindFile = FindFirstFileW(pszFile, &FileData);
1089 if (hFindFile == INVALID_HANDLE_VALUE)
1090 return FALSE;
1091 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001092 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001093 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001094 info->dwFileAttributes = FileData.dwFileAttributes;
1095 info->ftCreationTime = FileData.ftCreationTime;
1096 info->ftLastAccessTime = FileData.ftLastAccessTime;
1097 info->ftLastWriteTime = FileData.ftLastWriteTime;
1098 info->nFileSizeHigh = FileData.nFileSizeHigh;
1099 info->nFileSizeLow = FileData.nFileSizeLow;
1100/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001101 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1102 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001103 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001104}
1105
Brian Curtind25aef52011-06-13 15:16:04 -05001106/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1107static int has_GetFinalPathNameByHandle = 0;
1108static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1109 DWORD);
1110static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1111 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001112static int
Brian Curtind25aef52011-06-13 15:16:04 -05001113check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001114{
Brian Curtind25aef52011-06-13 15:16:04 -05001115 HINSTANCE hKernel32;
1116 /* only recheck */
1117 if (!has_GetFinalPathNameByHandle)
1118 {
1119 hKernel32 = GetModuleHandle("KERNEL32");
1120 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1121 "GetFinalPathNameByHandleA");
1122 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1123 "GetFinalPathNameByHandleW");
1124 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1125 Py_GetFinalPathNameByHandleW;
1126 }
1127 return has_GetFinalPathNameByHandle;
1128}
1129
1130static BOOL
1131get_target_path(HANDLE hdl, wchar_t **target_path)
1132{
1133 int buf_size, result_length;
1134 wchar_t *buf;
1135
1136 /* We have a good handle to the target, use it to determine
1137 the target path name (then we'll call lstat on it). */
1138 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1139 VOLUME_NAME_DOS);
1140 if(!buf_size)
1141 return FALSE;
1142
1143 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001144 if (!buf) {
1145 SetLastError(ERROR_OUTOFMEMORY);
1146 return FALSE;
1147 }
1148
Brian Curtind25aef52011-06-13 15:16:04 -05001149 result_length = Py_GetFinalPathNameByHandleW(hdl,
1150 buf, buf_size, VOLUME_NAME_DOS);
1151
1152 if(!result_length) {
1153 free(buf);
1154 return FALSE;
1155 }
1156
1157 if(!CloseHandle(hdl)) {
1158 free(buf);
1159 return FALSE;
1160 }
1161
1162 buf[result_length] = 0;
1163
1164 *target_path = buf;
1165 return TRUE;
1166}
1167
1168static int
1169win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1170 BOOL traverse);
1171static int
1172win32_xstat_impl(const char *path, struct win32_stat *result,
1173 BOOL traverse)
1174{
Victor Stinner26de69d2011-06-17 15:15:38 +02001175 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001176 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001177 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001178 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001179 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001180 const char *dot;
1181
Brian Curtind25aef52011-06-13 15:16:04 -05001182 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001183 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1184 traverse reparse point. */
1185 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001186 }
1187
Brian Curtinf5e76d02010-11-24 13:14:05 +00001188 hFile = CreateFileA(
1189 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001190 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001191 0, /* share mode */
1192 NULL, /* security attributes */
1193 OPEN_EXISTING,
1194 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001195 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1196 Because of this, calls like GetFinalPathNameByHandle will return
1197 the symlink path agin and not the actual final path. */
1198 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1199 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001200 NULL);
1201
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001202 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001203 /* Either the target doesn't exist, or we don't have access to
1204 get a handle to it. If the former, we need to return an error.
1205 If the latter, we can use attributes_from_dir. */
1206 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001207 return -1;
1208 /* Could not get attributes on open file. Fall back to
1209 reading the directory. */
1210 if (!attributes_from_dir(path, &info, &reparse_tag))
1211 /* Very strange. This should not fail now */
1212 return -1;
1213 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1214 if (traverse) {
1215 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001216 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001217 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001218 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001219 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001220 } else {
1221 if (!GetFileInformationByHandle(hFile, &info)) {
1222 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001223 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001224 }
1225 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001226 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1227 return -1;
1228
1229 /* Close the outer open file handle now that we're about to
1230 reopen it with different flags. */
1231 if (!CloseHandle(hFile))
1232 return -1;
1233
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001234 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001235 /* In order to call GetFinalPathNameByHandle we need to open
1236 the file without the reparse handling flag set. */
1237 hFile2 = CreateFileA(
1238 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1239 NULL, OPEN_EXISTING,
1240 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1241 NULL);
1242 if (hFile2 == INVALID_HANDLE_VALUE)
1243 return -1;
1244
1245 if (!get_target_path(hFile2, &target_path))
1246 return -1;
1247
1248 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001249 free(target_path);
1250 return code;
1251 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001252 } else
1253 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001254 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001255 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001256
1257 /* Set S_IEXEC if it is an .exe, .bat, ... */
1258 dot = strrchr(path, '.');
1259 if (dot) {
1260 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1261 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1262 result->st_mode |= 0111;
1263 }
1264 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001265}
1266
1267static int
Brian Curtind25aef52011-06-13 15:16:04 -05001268win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1269 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001270{
1271 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001272 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001273 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001274 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001275 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001276 const wchar_t *dot;
1277
Brian Curtind25aef52011-06-13 15:16:04 -05001278 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001279 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1280 traverse reparse point. */
1281 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001282 }
1283
Brian Curtinf5e76d02010-11-24 13:14:05 +00001284 hFile = CreateFileW(
1285 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001286 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001287 0, /* share mode */
1288 NULL, /* security attributes */
1289 OPEN_EXISTING,
1290 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001291 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1292 Because of this, calls like GetFinalPathNameByHandle will return
1293 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001294 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001295 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001296 NULL);
1297
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001298 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001299 /* Either the target doesn't exist, or we don't have access to
1300 get a handle to it. If the former, we need to return an error.
1301 If the latter, we can use attributes_from_dir. */
1302 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001303 return -1;
1304 /* Could not get attributes on open file. Fall back to
1305 reading the directory. */
1306 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1307 /* Very strange. This should not fail now */
1308 return -1;
1309 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1310 if (traverse) {
1311 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001312 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001313 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001314 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001315 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001316 } else {
1317 if (!GetFileInformationByHandle(hFile, &info)) {
1318 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001319 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001320 }
1321 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001322 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1323 return -1;
1324
1325 /* Close the outer open file handle now that we're about to
1326 reopen it with different flags. */
1327 if (!CloseHandle(hFile))
1328 return -1;
1329
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001330 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001331 /* In order to call GetFinalPathNameByHandle we need to open
1332 the file without the reparse handling flag set. */
1333 hFile2 = CreateFileW(
1334 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1335 NULL, OPEN_EXISTING,
1336 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1337 NULL);
1338 if (hFile2 == INVALID_HANDLE_VALUE)
1339 return -1;
1340
1341 if (!get_target_path(hFile2, &target_path))
1342 return -1;
1343
1344 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001345 free(target_path);
1346 return code;
1347 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001348 } else
1349 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001350 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001351 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001352
1353 /* Set S_IEXEC if it is an .exe, .bat, ... */
1354 dot = wcsrchr(path, '.');
1355 if (dot) {
1356 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1357 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1358 result->st_mode |= 0111;
1359 }
1360 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001361}
1362
1363static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001364win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001365{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001366 /* Protocol violation: we explicitly clear errno, instead of
1367 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001368 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001369 errno = 0;
1370 return code;
1371}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001372
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001373static int
1374win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1375{
1376 /* Protocol violation: we explicitly clear errno, instead of
1377 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001378 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001379 errno = 0;
1380 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001381}
Brian Curtind25aef52011-06-13 15:16:04 -05001382/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001383
1384 In Posix, stat automatically traverses symlinks and returns the stat
1385 structure for the target. In Windows, the equivalent GetFileAttributes by
1386 default does not traverse symlinks and instead returns attributes for
1387 the symlink.
1388
1389 Therefore, win32_lstat will get the attributes traditionally, and
1390 win32_stat will first explicitly resolve the symlink target and then will
1391 call win32_lstat on that result.
1392
Ezio Melotti4969f702011-03-15 05:59:46 +02001393 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001394
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001395static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001396win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001397{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001398 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001399}
1400
Victor Stinner8c62be82010-05-06 00:08:46 +00001401static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001402win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001403{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001404 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001405}
1406
1407static int
1408win32_stat(const char* path, struct win32_stat *result)
1409{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001410 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001411}
1412
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001413static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001414win32_stat_w(const wchar_t* path, struct win32_stat *result)
1415{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001416 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001417}
1418
1419static int
1420win32_fstat(int file_number, struct win32_stat *result)
1421{
Victor Stinner8c62be82010-05-06 00:08:46 +00001422 BY_HANDLE_FILE_INFORMATION info;
1423 HANDLE h;
1424 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001425
Victor Stinner8c62be82010-05-06 00:08:46 +00001426 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001427
Victor Stinner8c62be82010-05-06 00:08:46 +00001428 /* Protocol violation: we explicitly clear errno, instead of
1429 setting it to a POSIX error. Callers should use GetLastError. */
1430 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001431
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 if (h == INVALID_HANDLE_VALUE) {
1433 /* This is really a C library error (invalid file handle).
1434 We set the Win32 error to the closes one matching. */
1435 SetLastError(ERROR_INVALID_HANDLE);
1436 return -1;
1437 }
1438 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001439
Victor Stinner8c62be82010-05-06 00:08:46 +00001440 type = GetFileType(h);
1441 if (type == FILE_TYPE_UNKNOWN) {
1442 DWORD error = GetLastError();
1443 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001444 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001445 }
1446 /* else: valid but unknown file */
1447 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001448
Victor Stinner8c62be82010-05-06 00:08:46 +00001449 if (type != FILE_TYPE_DISK) {
1450 if (type == FILE_TYPE_CHAR)
1451 result->st_mode = _S_IFCHR;
1452 else if (type == FILE_TYPE_PIPE)
1453 result->st_mode = _S_IFIFO;
1454 return 0;
1455 }
1456
1457 if (!GetFileInformationByHandle(h, &info)) {
1458 return -1;
1459 }
1460
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001461 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001462 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001463 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1464 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001465}
1466
1467#endif /* MS_WINDOWS */
1468
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001469PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001470"stat_result: Result from stat or lstat.\n\n\
1471This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001472 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001473or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1474\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001475Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1476or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001477\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001478See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001479
1480static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001481 {"st_mode", "protection bits"},
1482 {"st_ino", "inode"},
1483 {"st_dev", "device"},
1484 {"st_nlink", "number of hard links"},
1485 {"st_uid", "user ID of owner"},
1486 {"st_gid", "group ID of owner"},
1487 {"st_size", "total size, in bytes"},
1488 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1489 {NULL, "integer time of last access"},
1490 {NULL, "integer time of last modification"},
1491 {NULL, "integer time of last change"},
1492 {"st_atime", "time of last access"},
1493 {"st_mtime", "time of last modification"},
1494 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001495#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001496 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001497#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001498#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001499 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001500#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001501#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001502 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001503#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001504#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001505 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001506#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001507#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001509#endif
1510#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001511 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001512#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001513 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001514};
1515
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001516#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001517#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001518#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001519#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001520#endif
1521
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001522#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001523#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1524#else
1525#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1526#endif
1527
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001528#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001529#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1530#else
1531#define ST_RDEV_IDX ST_BLOCKS_IDX
1532#endif
1533
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001534#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1535#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1536#else
1537#define ST_FLAGS_IDX ST_RDEV_IDX
1538#endif
1539
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001540#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001541#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001542#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001543#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001544#endif
1545
1546#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1547#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1548#else
1549#define ST_BIRTHTIME_IDX ST_GEN_IDX
1550#endif
1551
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001552static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001553 "stat_result", /* name */
1554 stat_result__doc__, /* doc */
1555 stat_result_fields,
1556 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001557};
1558
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001559PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001560"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1561This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001562 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001563or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001564\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001565See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001566
1567static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001568 {"f_bsize", },
1569 {"f_frsize", },
1570 {"f_blocks", },
1571 {"f_bfree", },
1572 {"f_bavail", },
1573 {"f_files", },
1574 {"f_ffree", },
1575 {"f_favail", },
1576 {"f_flag", },
1577 {"f_namemax",},
1578 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001579};
1580
1581static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001582 "statvfs_result", /* name */
1583 statvfs_result__doc__, /* doc */
1584 statvfs_result_fields,
1585 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001586};
1587
Ross Lagerwall7807c352011-03-17 20:20:30 +02001588#if defined(HAVE_WAITID) && !defined(__APPLE__)
1589PyDoc_STRVAR(waitid_result__doc__,
1590"waitid_result: Result from waitid.\n\n\
1591This object may be accessed either as a tuple of\n\
1592 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1593or via the attributes si_pid, si_uid, and so on.\n\
1594\n\
1595See os.waitid for more information.");
1596
1597static PyStructSequence_Field waitid_result_fields[] = {
1598 {"si_pid", },
1599 {"si_uid", },
1600 {"si_signo", },
1601 {"si_status", },
1602 {"si_code", },
1603 {0}
1604};
1605
1606static PyStructSequence_Desc waitid_result_desc = {
1607 "waitid_result", /* name */
1608 waitid_result__doc__, /* doc */
1609 waitid_result_fields,
1610 5
1611};
1612static PyTypeObject WaitidResultType;
1613#endif
1614
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001615static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001616static PyTypeObject StatResultType;
1617static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001618#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001619static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001620#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001621static newfunc structseq_new;
1622
1623static PyObject *
1624statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1625{
Victor Stinner8c62be82010-05-06 00:08:46 +00001626 PyStructSequence *result;
1627 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001628
Victor Stinner8c62be82010-05-06 00:08:46 +00001629 result = (PyStructSequence*)structseq_new(type, args, kwds);
1630 if (!result)
1631 return NULL;
1632 /* If we have been initialized from a tuple,
1633 st_?time might be set to None. Initialize it
1634 from the int slots. */
1635 for (i = 7; i <= 9; i++) {
1636 if (result->ob_item[i+3] == Py_None) {
1637 Py_DECREF(Py_None);
1638 Py_INCREF(result->ob_item[i]);
1639 result->ob_item[i+3] = result->ob_item[i];
1640 }
1641 }
1642 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001643}
1644
1645
1646
1647/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001648static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001649
1650PyDoc_STRVAR(stat_float_times__doc__,
1651"stat_float_times([newval]) -> oldval\n\n\
1652Determine whether os.[lf]stat represents time stamps as float objects.\n\
1653If newval is True, future calls to stat() return floats, if it is False,\n\
1654future calls return ints. \n\
1655If newval is omitted, return the current setting.\n");
1656
1657static PyObject*
1658stat_float_times(PyObject* self, PyObject *args)
1659{
Victor Stinner8c62be82010-05-06 00:08:46 +00001660 int newval = -1;
1661 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1662 return NULL;
1663 if (newval == -1)
1664 /* Return old value */
1665 return PyBool_FromLong(_stat_float_times);
1666 _stat_float_times = newval;
1667 Py_INCREF(Py_None);
1668 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001669}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001670
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001671static void
1672fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1673{
Victor Stinner8c62be82010-05-06 00:08:46 +00001674 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001675#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001676 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001677#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001678 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001679#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001680 if (!ival)
1681 return;
1682 if (_stat_float_times) {
1683 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1684 } else {
1685 fval = ival;
1686 Py_INCREF(fval);
1687 }
1688 PyStructSequence_SET_ITEM(v, index, ival);
1689 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001690}
1691
Tim Peters5aa91602002-01-30 05:46:57 +00001692/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001693 (used by posix_stat() and posix_fstat()) */
1694static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001695_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001696{
Victor Stinner8c62be82010-05-06 00:08:46 +00001697 unsigned long ansec, mnsec, cnsec;
1698 PyObject *v = PyStructSequence_New(&StatResultType);
1699 if (v == NULL)
1700 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001701
Victor Stinner8c62be82010-05-06 00:08:46 +00001702 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001703#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001704 PyStructSequence_SET_ITEM(v, 1,
1705 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001706#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001707 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001708#endif
1709#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001710 PyStructSequence_SET_ITEM(v, 2,
1711 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001712#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001713 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001714#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001715 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1716 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1717 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001718#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001719 PyStructSequence_SET_ITEM(v, 6,
1720 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001721#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001722 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001723#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001724
Martin v. Löwis14694662006-02-03 12:54:16 +00001725#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001726 ansec = st->st_atim.tv_nsec;
1727 mnsec = st->st_mtim.tv_nsec;
1728 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001729#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001730 ansec = st->st_atimespec.tv_nsec;
1731 mnsec = st->st_mtimespec.tv_nsec;
1732 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001733#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001734 ansec = st->st_atime_nsec;
1735 mnsec = st->st_mtime_nsec;
1736 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001737#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001738 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001739#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001740 fill_time(v, 7, st->st_atime, ansec);
1741 fill_time(v, 8, st->st_mtime, mnsec);
1742 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001743
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001744#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001745 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1746 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001747#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001748#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001749 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1750 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001751#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001752#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001753 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1754 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001755#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001756#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001757 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1758 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001759#endif
1760#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001761 {
1762 PyObject *val;
1763 unsigned long bsec,bnsec;
1764 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001765#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001766 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001767#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001769#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 if (_stat_float_times) {
1771 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1772 } else {
1773 val = PyLong_FromLong((long)bsec);
1774 }
1775 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1776 val);
1777 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001778#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001779#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001780 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1781 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001782#endif
Fred Drake699f3522000-06-29 21:12:41 +00001783
Victor Stinner8c62be82010-05-06 00:08:46 +00001784 if (PyErr_Occurred()) {
1785 Py_DECREF(v);
1786 return NULL;
1787 }
Fred Drake699f3522000-06-29 21:12:41 +00001788
Victor Stinner8c62be82010-05-06 00:08:46 +00001789 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001790}
1791
Barry Warsaw53699e91996-12-10 23:23:01 +00001792static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001793posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001795#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001796 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001797#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001798 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001799#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001800 char *wformat,
1801 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001802{
Victor Stinner8c62be82010-05-06 00:08:46 +00001803 STRUCT_STAT st;
1804 PyObject *opath;
1805 char *path;
1806 int res;
1807 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001808
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001809#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001810 PyUnicodeObject *po;
1811 if (PyArg_ParseTuple(args, wformat, &po)) {
1812 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001813
Victor Stinner8c62be82010-05-06 00:08:46 +00001814 Py_BEGIN_ALLOW_THREADS
1815 /* PyUnicode_AS_UNICODE result OK without
1816 thread lock as it is a simple dereference. */
1817 res = wstatfunc(wpath, &st);
1818 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001819
Victor Stinner8c62be82010-05-06 00:08:46 +00001820 if (res != 0)
1821 return win32_error_unicode("stat", wpath);
1822 return _pystat_fromstructstat(&st);
1823 }
1824 /* Drop the argument parsing error as narrow strings
1825 are also valid. */
1826 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001827#endif
1828
Victor Stinner8c62be82010-05-06 00:08:46 +00001829 if (!PyArg_ParseTuple(args, format,
1830 PyUnicode_FSConverter, &opath))
1831 return NULL;
1832 path = PyBytes_AsString(opath);
1833 Py_BEGIN_ALLOW_THREADS
1834 res = (*statfunc)(path, &st);
1835 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001836
Victor Stinner8c62be82010-05-06 00:08:46 +00001837 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001838#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001840#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001841 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001842#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001843 }
1844 else
1845 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001846
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 Py_DECREF(opath);
1848 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001849}
1850
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001851/* POSIX methods */
1852
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001853PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001854"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001855Use the real uid/gid to test for access to a path. Note that most\n\
1856operations will use the effective uid/gid, therefore this routine can\n\
1857be used in a suid/sgid environment to test if the invoking user has the\n\
1858specified access to the path. The mode argument can be F_OK to test\n\
1859existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001860
1861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001862posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001863{
Victor Stinner8c62be82010-05-06 00:08:46 +00001864 PyObject *opath;
1865 char *path;
1866 int mode;
1867
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001868#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001869 DWORD attr;
1870 PyUnicodeObject *po;
1871 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1872 Py_BEGIN_ALLOW_THREADS
1873 /* PyUnicode_AS_UNICODE OK without thread lock as
1874 it is a simple dereference. */
1875 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1876 Py_END_ALLOW_THREADS
1877 goto finish;
1878 }
1879 /* Drop the argument parsing error as narrow strings
1880 are also valid. */
1881 PyErr_Clear();
1882 if (!PyArg_ParseTuple(args, "O&i:access",
1883 PyUnicode_FSConverter, &opath, &mode))
1884 return NULL;
1885 path = PyBytes_AsString(opath);
1886 Py_BEGIN_ALLOW_THREADS
1887 attr = GetFileAttributesA(path);
1888 Py_END_ALLOW_THREADS
1889 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001890finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001891 if (attr == 0xFFFFFFFF)
1892 /* File does not exist, or cannot read attributes */
1893 return PyBool_FromLong(0);
1894 /* Access is possible if either write access wasn't requested, or
1895 the file isn't read-only, or if it's a directory, as there are
1896 no read-only directories on Windows. */
1897 return PyBool_FromLong(!(mode & 2)
1898 || !(attr & FILE_ATTRIBUTE_READONLY)
1899 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001900#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 int res;
1902 if (!PyArg_ParseTuple(args, "O&i:access",
1903 PyUnicode_FSConverter, &opath, &mode))
1904 return NULL;
1905 path = PyBytes_AsString(opath);
1906 Py_BEGIN_ALLOW_THREADS
1907 res = access(path, mode);
1908 Py_END_ALLOW_THREADS
1909 Py_DECREF(opath);
1910 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001911#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001912}
1913
Guido van Rossumd371ff11999-01-25 16:12:23 +00001914#ifndef F_OK
1915#define F_OK 0
1916#endif
1917#ifndef R_OK
1918#define R_OK 4
1919#endif
1920#ifndef W_OK
1921#define W_OK 2
1922#endif
1923#ifndef X_OK
1924#define X_OK 1
1925#endif
1926
1927#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001928PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001929"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001930Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001931
1932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001933posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001934{
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 int id;
1936 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001937
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1939 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001940
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001941#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001942 /* file descriptor 0 only, the default input device (stdin) */
1943 if (id == 0) {
1944 ret = ttyname();
1945 }
1946 else {
1947 ret = NULL;
1948 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001949#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001951#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001952 if (ret == NULL)
1953 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001954 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001955}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001956#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001957
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001958#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001959PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001960"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001961Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001962
1963static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001964posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001965{
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 char *ret;
1967 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001968
Greg Wardb48bc172000-03-01 21:51:56 +00001969#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001971#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001972 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001973#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 if (ret == NULL)
1975 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001976 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001977}
1978#endif
1979
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001980PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001981"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001982Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001983
Barry Warsaw53699e91996-12-10 23:23:01 +00001984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001985posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001986{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001987#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001988 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001989#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001991#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001992 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001993#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001994 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001995#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001996}
1997
Fred Drake4d1e64b2002-04-15 19:40:07 +00001998#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001999PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002000"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00002001Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002002opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002003
2004static PyObject *
2005posix_fchdir(PyObject *self, PyObject *fdobj)
2006{
Victor Stinner8c62be82010-05-06 00:08:46 +00002007 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002008}
2009#endif /* HAVE_FCHDIR */
2010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002011
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002012PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002013"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002014Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002015
Barry Warsaw53699e91996-12-10 23:23:01 +00002016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002017posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002018{
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 PyObject *opath = NULL;
2020 char *path = NULL;
2021 int i;
2022 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002023#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002024 DWORD attr;
2025 PyUnicodeObject *po;
2026 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
2027 Py_BEGIN_ALLOW_THREADS
2028 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
2029 if (attr != 0xFFFFFFFF) {
2030 if (i & _S_IWRITE)
2031 attr &= ~FILE_ATTRIBUTE_READONLY;
2032 else
2033 attr |= FILE_ATTRIBUTE_READONLY;
2034 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
2035 }
2036 else
2037 res = 0;
2038 Py_END_ALLOW_THREADS
2039 if (!res)
2040 return win32_error_unicode("chmod",
2041 PyUnicode_AS_UNICODE(po));
2042 Py_INCREF(Py_None);
2043 return Py_None;
2044 }
2045 /* Drop the argument parsing error as narrow strings
2046 are also valid. */
2047 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002048
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2050 &opath, &i))
2051 return NULL;
2052 path = PyBytes_AsString(opath);
2053 Py_BEGIN_ALLOW_THREADS
2054 attr = GetFileAttributesA(path);
2055 if (attr != 0xFFFFFFFF) {
2056 if (i & _S_IWRITE)
2057 attr &= ~FILE_ATTRIBUTE_READONLY;
2058 else
2059 attr |= FILE_ATTRIBUTE_READONLY;
2060 res = SetFileAttributesA(path, attr);
2061 }
2062 else
2063 res = 0;
2064 Py_END_ALLOW_THREADS
2065 if (!res) {
2066 win32_error("chmod", path);
2067 Py_DECREF(opath);
2068 return NULL;
2069 }
2070 Py_DECREF(opath);
2071 Py_INCREF(Py_None);
2072 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002073#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00002074 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2075 &opath, &i))
2076 return NULL;
2077 path = PyBytes_AsString(opath);
2078 Py_BEGIN_ALLOW_THREADS
2079 res = chmod(path, i);
2080 Py_END_ALLOW_THREADS
2081 if (res < 0)
2082 return posix_error_with_allocated_filename(opath);
2083 Py_DECREF(opath);
2084 Py_INCREF(Py_None);
2085 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002086#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002087}
2088
Christian Heimes4e30a842007-11-30 22:12:06 +00002089#ifdef HAVE_FCHMOD
2090PyDoc_STRVAR(posix_fchmod__doc__,
2091"fchmod(fd, mode)\n\n\
2092Change the access permissions of the file given by file\n\
2093descriptor fd.");
2094
2095static PyObject *
2096posix_fchmod(PyObject *self, PyObject *args)
2097{
Victor Stinner8c62be82010-05-06 00:08:46 +00002098 int fd, mode, res;
2099 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2100 return NULL;
2101 Py_BEGIN_ALLOW_THREADS
2102 res = fchmod(fd, mode);
2103 Py_END_ALLOW_THREADS
2104 if (res < 0)
2105 return posix_error();
2106 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002107}
2108#endif /* HAVE_FCHMOD */
2109
2110#ifdef HAVE_LCHMOD
2111PyDoc_STRVAR(posix_lchmod__doc__,
2112"lchmod(path, mode)\n\n\
2113Change the access permissions of a file. If path is a symlink, this\n\
2114affects the link itself rather than the target.");
2115
2116static PyObject *
2117posix_lchmod(PyObject *self, PyObject *args)
2118{
Victor Stinner8c62be82010-05-06 00:08:46 +00002119 PyObject *opath;
2120 char *path;
2121 int i;
2122 int res;
2123 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2124 &opath, &i))
2125 return NULL;
2126 path = PyBytes_AsString(opath);
2127 Py_BEGIN_ALLOW_THREADS
2128 res = lchmod(path, i);
2129 Py_END_ALLOW_THREADS
2130 if (res < 0)
2131 return posix_error_with_allocated_filename(opath);
2132 Py_DECREF(opath);
2133 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002134}
2135#endif /* HAVE_LCHMOD */
2136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002137
Thomas Wouterscf297e42007-02-23 15:07:44 +00002138#ifdef HAVE_CHFLAGS
2139PyDoc_STRVAR(posix_chflags__doc__,
2140"chflags(path, flags)\n\n\
2141Set file flags.");
2142
2143static PyObject *
2144posix_chflags(PyObject *self, PyObject *args)
2145{
Victor Stinner8c62be82010-05-06 00:08:46 +00002146 PyObject *opath;
2147 char *path;
2148 unsigned long flags;
2149 int res;
2150 if (!PyArg_ParseTuple(args, "O&k:chflags",
2151 PyUnicode_FSConverter, &opath, &flags))
2152 return NULL;
2153 path = PyBytes_AsString(opath);
2154 Py_BEGIN_ALLOW_THREADS
2155 res = chflags(path, flags);
2156 Py_END_ALLOW_THREADS
2157 if (res < 0)
2158 return posix_error_with_allocated_filename(opath);
2159 Py_DECREF(opath);
2160 Py_INCREF(Py_None);
2161 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002162}
2163#endif /* HAVE_CHFLAGS */
2164
2165#ifdef HAVE_LCHFLAGS
2166PyDoc_STRVAR(posix_lchflags__doc__,
2167"lchflags(path, flags)\n\n\
2168Set file flags.\n\
2169This function will not follow symbolic links.");
2170
2171static PyObject *
2172posix_lchflags(PyObject *self, PyObject *args)
2173{
Victor Stinner8c62be82010-05-06 00:08:46 +00002174 PyObject *opath;
2175 char *path;
2176 unsigned long flags;
2177 int res;
2178 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2179 PyUnicode_FSConverter, &opath, &flags))
2180 return NULL;
2181 path = PyBytes_AsString(opath);
2182 Py_BEGIN_ALLOW_THREADS
2183 res = lchflags(path, flags);
2184 Py_END_ALLOW_THREADS
2185 if (res < 0)
2186 return posix_error_with_allocated_filename(opath);
2187 Py_DECREF(opath);
2188 Py_INCREF(Py_None);
2189 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002190}
2191#endif /* HAVE_LCHFLAGS */
2192
Martin v. Löwis244edc82001-10-04 22:44:26 +00002193#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002194PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002195"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002196Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002197
2198static PyObject *
2199posix_chroot(PyObject *self, PyObject *args)
2200{
Victor Stinner8c62be82010-05-06 00:08:46 +00002201 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002202}
2203#endif
2204
Guido van Rossum21142a01999-01-08 21:05:37 +00002205#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002206PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002207"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002208force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002209
2210static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002211posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002212{
Stefan Krah0e803b32010-11-26 16:16:47 +00002213 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002214}
2215#endif /* HAVE_FSYNC */
2216
Ross Lagerwall7807c352011-03-17 20:20:30 +02002217#ifdef HAVE_SYNC
2218PyDoc_STRVAR(posix_sync__doc__,
2219"sync()\n\n\
2220Force write of everything to disk.");
2221
2222static PyObject *
2223posix_sync(PyObject *self, PyObject *noargs)
2224{
2225 Py_BEGIN_ALLOW_THREADS
2226 sync();
2227 Py_END_ALLOW_THREADS
2228 Py_RETURN_NONE;
2229}
2230#endif
2231
Guido van Rossum21142a01999-01-08 21:05:37 +00002232#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002233
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002234#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002235extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2236#endif
2237
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002238PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002239"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002240force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002241 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002242
2243static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002244posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002245{
Stefan Krah0e803b32010-11-26 16:16:47 +00002246 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002247}
2248#endif /* HAVE_FDATASYNC */
2249
2250
Fredrik Lundh10723342000-07-10 16:38:09 +00002251#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002252PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002253"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002254Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002255
Barry Warsaw53699e91996-12-10 23:23:01 +00002256static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002257posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002258{
Victor Stinner8c62be82010-05-06 00:08:46 +00002259 PyObject *opath;
2260 char *path;
2261 long uid, gid;
2262 int res;
2263 if (!PyArg_ParseTuple(args, "O&ll:chown",
2264 PyUnicode_FSConverter, &opath,
2265 &uid, &gid))
2266 return NULL;
2267 path = PyBytes_AsString(opath);
2268 Py_BEGIN_ALLOW_THREADS
2269 res = chown(path, (uid_t) uid, (gid_t) gid);
2270 Py_END_ALLOW_THREADS
2271 if (res < 0)
2272 return posix_error_with_allocated_filename(opath);
2273 Py_DECREF(opath);
2274 Py_INCREF(Py_None);
2275 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002276}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002277#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002278
Christian Heimes4e30a842007-11-30 22:12:06 +00002279#ifdef HAVE_FCHOWN
2280PyDoc_STRVAR(posix_fchown__doc__,
2281"fchown(fd, uid, gid)\n\n\
2282Change the owner and group id of the file given by file descriptor\n\
2283fd to the numeric uid and gid.");
2284
2285static PyObject *
2286posix_fchown(PyObject *self, PyObject *args)
2287{
Victor Stinner8c62be82010-05-06 00:08:46 +00002288 int fd;
2289 long uid, gid;
2290 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002291 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002292 return NULL;
2293 Py_BEGIN_ALLOW_THREADS
2294 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2295 Py_END_ALLOW_THREADS
2296 if (res < 0)
2297 return posix_error();
2298 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002299}
2300#endif /* HAVE_FCHOWN */
2301
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002302#ifdef HAVE_LCHOWN
2303PyDoc_STRVAR(posix_lchown__doc__,
2304"lchown(path, uid, gid)\n\n\
2305Change the owner and group id of path to the numeric uid and gid.\n\
2306This function will not follow symbolic links.");
2307
2308static PyObject *
2309posix_lchown(PyObject *self, PyObject *args)
2310{
Victor Stinner8c62be82010-05-06 00:08:46 +00002311 PyObject *opath;
2312 char *path;
2313 long uid, gid;
2314 int res;
2315 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2316 PyUnicode_FSConverter, &opath,
2317 &uid, &gid))
2318 return NULL;
2319 path = PyBytes_AsString(opath);
2320 Py_BEGIN_ALLOW_THREADS
2321 res = lchown(path, (uid_t) uid, (gid_t) gid);
2322 Py_END_ALLOW_THREADS
2323 if (res < 0)
2324 return posix_error_with_allocated_filename(opath);
2325 Py_DECREF(opath);
2326 Py_INCREF(Py_None);
2327 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002328}
2329#endif /* HAVE_LCHOWN */
2330
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002331
Guido van Rossum36bc6801995-06-14 22:54:23 +00002332#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002333static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002334posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002335{
Victor Stinner8c62be82010-05-06 00:08:46 +00002336 char buf[1026];
2337 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002338
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002339#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002340 if (!use_bytes) {
2341 wchar_t wbuf[1026];
2342 wchar_t *wbuf2 = wbuf;
2343 PyObject *resobj;
2344 DWORD len;
2345 Py_BEGIN_ALLOW_THREADS
2346 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2347 /* If the buffer is large enough, len does not include the
2348 terminating \0. If the buffer is too small, len includes
2349 the space needed for the terminator. */
2350 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2351 wbuf2 = malloc(len * sizeof(wchar_t));
2352 if (wbuf2)
2353 len = GetCurrentDirectoryW(len, wbuf2);
2354 }
2355 Py_END_ALLOW_THREADS
2356 if (!wbuf2) {
2357 PyErr_NoMemory();
2358 return NULL;
2359 }
2360 if (!len) {
2361 if (wbuf2 != wbuf) free(wbuf2);
2362 return win32_error("getcwdu", NULL);
2363 }
2364 resobj = PyUnicode_FromWideChar(wbuf2, len);
2365 if (wbuf2 != wbuf) free(wbuf2);
2366 return resobj;
2367 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002368#endif
2369
Victor Stinner8c62be82010-05-06 00:08:46 +00002370 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002371#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002372 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002373#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002374 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002375#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002376 Py_END_ALLOW_THREADS
2377 if (res == NULL)
2378 return posix_error();
2379 if (use_bytes)
2380 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002381 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002382}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002383
2384PyDoc_STRVAR(posix_getcwd__doc__,
2385"getcwd() -> path\n\n\
2386Return a unicode string representing the current working directory.");
2387
2388static PyObject *
2389posix_getcwd_unicode(PyObject *self)
2390{
2391 return posix_getcwd(0);
2392}
2393
2394PyDoc_STRVAR(posix_getcwdb__doc__,
2395"getcwdb() -> path\n\n\
2396Return a bytes string representing the current working directory.");
2397
2398static PyObject *
2399posix_getcwd_bytes(PyObject *self)
2400{
2401 return posix_getcwd(1);
2402}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002403#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002404
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002405
Guido van Rossumb6775db1994-08-01 11:34:53 +00002406#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002407PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002408"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002409Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002410
Barry Warsaw53699e91996-12-10 23:23:01 +00002411static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002412posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002413{
Victor Stinner8c62be82010-05-06 00:08:46 +00002414 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002415}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002416#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002417
Brian Curtin1b9df392010-11-24 20:24:31 +00002418#ifdef MS_WINDOWS
2419PyDoc_STRVAR(win32_link__doc__,
2420"link(src, dst)\n\n\
2421Create a hard link to a file.");
2422
2423static PyObject *
2424win32_link(PyObject *self, PyObject *args)
2425{
2426 PyObject *osrc, *odst;
2427 char *src, *dst;
2428 BOOL rslt;
2429
Brian Curtinfc889c42010-11-28 23:59:46 +00002430 PyUnicodeObject *usrc, *udst;
2431 if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst)) {
2432 Py_BEGIN_ALLOW_THREADS
2433 rslt = CreateHardLinkW(PyUnicode_AS_UNICODE(udst),
2434 PyUnicode_AS_UNICODE(usrc), NULL);
2435 Py_END_ALLOW_THREADS
2436
2437 if (rslt == 0)
2438 return win32_error("link", NULL);
2439
2440 Py_RETURN_NONE;
2441 }
2442
2443 /* Narrow strings also valid. */
2444 PyErr_Clear();
2445
Brian Curtin1b9df392010-11-24 20:24:31 +00002446 if (!PyArg_ParseTuple(args, "O&O&:link", PyUnicode_FSConverter, &osrc,
2447 PyUnicode_FSConverter, &odst))
2448 return NULL;
2449
2450 src = PyBytes_AsString(osrc);
2451 dst = PyBytes_AsString(odst);
2452
2453 Py_BEGIN_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00002454 rslt = CreateHardLinkA(dst, src, NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002455 Py_END_ALLOW_THREADS
2456
Stefan Krah30b341f2010-11-27 11:44:18 +00002457 Py_DECREF(osrc);
2458 Py_DECREF(odst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002459 if (rslt == 0)
Brian Curtinfc889c42010-11-28 23:59:46 +00002460 return win32_error("link", NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002461
2462 Py_RETURN_NONE;
2463}
2464#endif /* MS_WINDOWS */
2465
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002467PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002468"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002469Return a list containing the names of the entries in the directory.\n\
2470\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002471 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002472\n\
2473The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002474entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002475
Barry Warsaw53699e91996-12-10 23:23:01 +00002476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002477posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002478{
Victor Stinner8c62be82010-05-06 00:08:46 +00002479 /* XXX Should redo this putting the (now four) versions of opendir
2480 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002481#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002482
Victor Stinner8c62be82010-05-06 00:08:46 +00002483 PyObject *d, *v;
2484 HANDLE hFindFile;
2485 BOOL result;
2486 WIN32_FIND_DATA FileData;
2487 PyObject *opath;
2488 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2489 char *bufptr = namebuf;
2490 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002491
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002492 PyObject *po = NULL;
2493 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002494 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002495 Py_UNICODE *wnamebuf, *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002496
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002497 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002498 po_wchars = L".";
2499 len = 1;
2500 } else {
2501 po_wchars = PyUnicode_AS_UNICODE(po);
2502 len = PyUnicode_GET_SIZE(po);
2503 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002504 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002505 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2506 if (!wnamebuf) {
2507 PyErr_NoMemory();
2508 return NULL;
2509 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002510 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002511 if (len > 0) {
2512 Py_UNICODE wch = wnamebuf[len-1];
2513 if (wch != L'/' && wch != L'\\' && wch != L':')
2514 wnamebuf[len++] = L'\\';
2515 wcscpy(wnamebuf + len, L"*.*");
2516 }
2517 if ((d = PyList_New(0)) == NULL) {
2518 free(wnamebuf);
2519 return NULL;
2520 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002521 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002522 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002523 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002524 if (hFindFile == INVALID_HANDLE_VALUE) {
2525 int error = GetLastError();
2526 if (error == ERROR_FILE_NOT_FOUND) {
2527 free(wnamebuf);
2528 return d;
2529 }
2530 Py_DECREF(d);
2531 win32_error_unicode("FindFirstFileW", wnamebuf);
2532 free(wnamebuf);
2533 return NULL;
2534 }
2535 do {
2536 /* Skip over . and .. */
2537 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2538 wcscmp(wFileData.cFileName, L"..") != 0) {
2539 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2540 if (v == NULL) {
2541 Py_DECREF(d);
2542 d = NULL;
2543 break;
2544 }
2545 if (PyList_Append(d, v) != 0) {
2546 Py_DECREF(v);
2547 Py_DECREF(d);
2548 d = NULL;
2549 break;
2550 }
2551 Py_DECREF(v);
2552 }
2553 Py_BEGIN_ALLOW_THREADS
2554 result = FindNextFileW(hFindFile, &wFileData);
2555 Py_END_ALLOW_THREADS
2556 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2557 it got to the end of the directory. */
2558 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2559 Py_DECREF(d);
2560 win32_error_unicode("FindNextFileW", wnamebuf);
2561 FindClose(hFindFile);
2562 free(wnamebuf);
2563 return NULL;
2564 }
2565 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002566
Victor Stinner8c62be82010-05-06 00:08:46 +00002567 if (FindClose(hFindFile) == FALSE) {
2568 Py_DECREF(d);
2569 win32_error_unicode("FindClose", wnamebuf);
2570 free(wnamebuf);
2571 return NULL;
2572 }
2573 free(wnamebuf);
2574 return d;
2575 }
2576 /* Drop the argument parsing error as narrow strings
2577 are also valid. */
2578 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002579
Victor Stinner8c62be82010-05-06 00:08:46 +00002580 if (!PyArg_ParseTuple(args, "O&:listdir",
2581 PyUnicode_FSConverter, &opath))
2582 return NULL;
2583 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2584 PyErr_SetString(PyExc_ValueError, "path too long");
2585 Py_DECREF(opath);
2586 return NULL;
2587 }
2588 strcpy(namebuf, PyBytes_AsString(opath));
2589 len = PyObject_Size(opath);
Stefan Krah2a7feee2010-11-27 22:06:49 +00002590 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002591 if (len > 0) {
2592 char ch = namebuf[len-1];
2593 if (ch != SEP && ch != ALTSEP && ch != ':')
2594 namebuf[len++] = '/';
2595 strcpy(namebuf + len, "*.*");
2596 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002597
Victor Stinner8c62be82010-05-06 00:08:46 +00002598 if ((d = PyList_New(0)) == NULL)
2599 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002600
Antoine Pitroub73caab2010-08-09 23:39:31 +00002601 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002602 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002603 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002604 if (hFindFile == INVALID_HANDLE_VALUE) {
2605 int error = GetLastError();
2606 if (error == ERROR_FILE_NOT_FOUND)
2607 return d;
2608 Py_DECREF(d);
2609 return win32_error("FindFirstFile", namebuf);
2610 }
2611 do {
2612 /* Skip over . and .. */
2613 if (strcmp(FileData.cFileName, ".") != 0 &&
2614 strcmp(FileData.cFileName, "..") != 0) {
2615 v = PyBytes_FromString(FileData.cFileName);
2616 if (v == NULL) {
2617 Py_DECREF(d);
2618 d = NULL;
2619 break;
2620 }
2621 if (PyList_Append(d, v) != 0) {
2622 Py_DECREF(v);
2623 Py_DECREF(d);
2624 d = NULL;
2625 break;
2626 }
2627 Py_DECREF(v);
2628 }
2629 Py_BEGIN_ALLOW_THREADS
2630 result = FindNextFile(hFindFile, &FileData);
2631 Py_END_ALLOW_THREADS
2632 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2633 it got to the end of the directory. */
2634 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2635 Py_DECREF(d);
2636 win32_error("FindNextFile", namebuf);
2637 FindClose(hFindFile);
2638 return NULL;
2639 }
2640 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002641
Victor Stinner8c62be82010-05-06 00:08:46 +00002642 if (FindClose(hFindFile) == FALSE) {
2643 Py_DECREF(d);
2644 return win32_error("FindClose", namebuf);
2645 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002646
Victor Stinner8c62be82010-05-06 00:08:46 +00002647 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002648
Tim Peters0bb44a42000-09-15 07:44:49 +00002649#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002650
2651#ifndef MAX_PATH
2652#define MAX_PATH CCHMAXPATH
2653#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002654 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002655 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002656 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002657 PyObject *d, *v;
2658 char namebuf[MAX_PATH+5];
2659 HDIR hdir = 1;
2660 ULONG srchcnt = 1;
2661 FILEFINDBUF3 ep;
2662 APIRET rc;
2663
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002665 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002666 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002667 name = PyBytes_AsString(oname);
2668 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002669 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002670 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002671 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002672 return NULL;
2673 }
2674 strcpy(namebuf, name);
2675 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002676 if (*pt == ALTSEP)
2677 *pt = SEP;
2678 if (namebuf[len-1] != SEP)
2679 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002680 strcpy(namebuf + len, "*.*");
2681
Neal Norwitz6c913782007-10-14 03:23:09 +00002682 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002683 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002684 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002685 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002686
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002687 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2688 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002689 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002690 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2691 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2692 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002693
2694 if (rc != NO_ERROR) {
2695 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002696 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002697 }
2698
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002699 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002700 do {
2701 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002702 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002703 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002704
2705 strcpy(namebuf, ep.achName);
2706
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002707 /* Leave Case of Name Alone -- In Native Form */
2708 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002709
Christian Heimes72b710a2008-05-26 13:28:38 +00002710 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002711 if (v == NULL) {
2712 Py_DECREF(d);
2713 d = NULL;
2714 break;
2715 }
2716 if (PyList_Append(d, v) != 0) {
2717 Py_DECREF(v);
2718 Py_DECREF(d);
2719 d = NULL;
2720 break;
2721 }
2722 Py_DECREF(v);
2723 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2724 }
2725
Victor Stinnerdcb24032010-04-22 12:08:36 +00002726 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002727 return d;
2728#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002729 PyObject *oname;
2730 char *name;
2731 PyObject *d, *v;
2732 DIR *dirp;
2733 struct dirent *ep;
2734 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002735
Victor Stinner8c62be82010-05-06 00:08:46 +00002736 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002737 /* v is never read, so it does not need to be initialized yet. */
2738 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002739 arg_is_unicode = 0;
2740 PyErr_Clear();
2741 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002742 oname = NULL;
2743 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002744 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002745 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002746 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002747 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002748 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002749 Py_BEGIN_ALLOW_THREADS
2750 dirp = opendir(name);
2751 Py_END_ALLOW_THREADS
2752 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002753 return posix_error_with_allocated_filename(oname);
2754 }
2755 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002756 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002757 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002758 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002759 Py_DECREF(oname);
2760 return NULL;
2761 }
2762 for (;;) {
2763 errno = 0;
2764 Py_BEGIN_ALLOW_THREADS
2765 ep = readdir(dirp);
2766 Py_END_ALLOW_THREADS
2767 if (ep == NULL) {
2768 if (errno == 0) {
2769 break;
2770 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002771 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002772 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002773 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002774 Py_DECREF(d);
2775 return posix_error_with_allocated_filename(oname);
2776 }
2777 }
2778 if (ep->d_name[0] == '.' &&
2779 (NAMLEN(ep) == 1 ||
2780 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2781 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002782 if (arg_is_unicode)
2783 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2784 else
2785 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002786 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002787 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002788 break;
2789 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002790 if (PyList_Append(d, v) != 0) {
2791 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002792 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002793 break;
2794 }
2795 Py_DECREF(v);
2796 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002797 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002798 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002799 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002800 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002801
Victor Stinner8c62be82010-05-06 00:08:46 +00002802 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002803
Tim Peters0bb44a42000-09-15 07:44:49 +00002804#endif /* which OS */
2805} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002806
Antoine Pitrou8250e232011-02-25 23:41:16 +00002807#ifdef HAVE_FDOPENDIR
2808PyDoc_STRVAR(posix_fdlistdir__doc__,
2809"fdlistdir(fd) -> list_of_strings\n\n\
2810Like listdir(), but uses a file descriptor instead.\n\
2811After succesful execution of this function, fd will be closed.");
2812
2813static PyObject *
2814posix_fdlistdir(PyObject *self, PyObject *args)
2815{
2816 PyObject *d, *v;
2817 DIR *dirp;
2818 struct dirent *ep;
2819 int fd;
2820
2821 errno = 0;
2822 if (!PyArg_ParseTuple(args, "i:fdlistdir", &fd))
2823 return NULL;
2824 Py_BEGIN_ALLOW_THREADS
2825 dirp = fdopendir(fd);
2826 Py_END_ALLOW_THREADS
2827 if (dirp == NULL) {
2828 close(fd);
2829 return posix_error();
2830 }
2831 if ((d = PyList_New(0)) == NULL) {
2832 Py_BEGIN_ALLOW_THREADS
2833 closedir(dirp);
2834 Py_END_ALLOW_THREADS
2835 return NULL;
2836 }
2837 for (;;) {
2838 errno = 0;
2839 Py_BEGIN_ALLOW_THREADS
2840 ep = readdir(dirp);
2841 Py_END_ALLOW_THREADS
2842 if (ep == NULL) {
2843 if (errno == 0) {
2844 break;
2845 } else {
2846 Py_BEGIN_ALLOW_THREADS
2847 closedir(dirp);
2848 Py_END_ALLOW_THREADS
2849 Py_DECREF(d);
2850 return posix_error();
2851 }
2852 }
2853 if (ep->d_name[0] == '.' &&
2854 (NAMLEN(ep) == 1 ||
2855 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2856 continue;
2857 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2858 if (v == NULL) {
2859 Py_CLEAR(d);
2860 break;
2861 }
2862 if (PyList_Append(d, v) != 0) {
2863 Py_DECREF(v);
2864 Py_CLEAR(d);
2865 break;
2866 }
2867 Py_DECREF(v);
2868 }
2869 Py_BEGIN_ALLOW_THREADS
2870 closedir(dirp);
2871 Py_END_ALLOW_THREADS
2872
2873 return d;
2874}
2875#endif
2876
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002877#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002878/* A helper function for abspath on win32 */
2879static PyObject *
2880posix__getfullpathname(PyObject *self, PyObject *args)
2881{
Victor Stinner8c62be82010-05-06 00:08:46 +00002882 PyObject *opath;
2883 char *path;
2884 char outbuf[MAX_PATH*2];
2885 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002886#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002887 PyUnicodeObject *po;
2888 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2889 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2890 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2891 Py_UNICODE *wtemp;
2892 DWORD result;
2893 PyObject *v;
2894 result = GetFullPathNameW(wpath,
2895 sizeof(woutbuf)/sizeof(woutbuf[0]),
2896 woutbuf, &wtemp);
2897 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2898 woutbufp = malloc(result * sizeof(Py_UNICODE));
2899 if (!woutbufp)
2900 return PyErr_NoMemory();
2901 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2902 }
2903 if (result)
2904 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2905 else
2906 v = win32_error_unicode("GetFullPathNameW", wpath);
2907 if (woutbufp != woutbuf)
2908 free(woutbufp);
2909 return v;
2910 }
2911 /* Drop the argument parsing error as narrow strings
2912 are also valid. */
2913 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002914
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002915#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2917 PyUnicode_FSConverter, &opath))
2918 return NULL;
2919 path = PyBytes_AsString(opath);
2920 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2921 outbuf, &temp)) {
2922 win32_error("GetFullPathName", path);
2923 Py_DECREF(opath);
2924 return NULL;
2925 }
2926 Py_DECREF(opath);
2927 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2928 return PyUnicode_Decode(outbuf, strlen(outbuf),
2929 Py_FileSystemDefaultEncoding, NULL);
2930 }
2931 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002932} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002933
Brian Curtind25aef52011-06-13 15:16:04 -05002934
Brian Curtinf5e76d02010-11-24 13:14:05 +00002935
Brian Curtind40e6f72010-07-08 21:39:08 +00002936/* A helper function for samepath on windows */
2937static PyObject *
2938posix__getfinalpathname(PyObject *self, PyObject *args)
2939{
2940 HANDLE hFile;
2941 int buf_size;
2942 wchar_t *target_path;
2943 int result_length;
2944 PyObject *result;
2945 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002946
Brian Curtin94622b02010-09-24 00:03:39 +00002947 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002948 return NULL;
2949 }
2950
2951 if(!check_GetFinalPathNameByHandle()) {
2952 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2953 NotImplementedError. */
2954 return PyErr_Format(PyExc_NotImplementedError,
2955 "GetFinalPathNameByHandle not available on this platform");
2956 }
2957
2958 hFile = CreateFileW(
2959 path,
2960 0, /* desired access */
2961 0, /* share mode */
2962 NULL, /* security attributes */
2963 OPEN_EXISTING,
2964 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2965 FILE_FLAG_BACKUP_SEMANTICS,
2966 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002967
Brian Curtind40e6f72010-07-08 21:39:08 +00002968 if(hFile == INVALID_HANDLE_VALUE) {
2969 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002970 return PyErr_Format(PyExc_RuntimeError,
2971 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002972 }
2973
2974 /* We have a good handle to the target, use it to determine the
2975 target path name. */
2976 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2977
2978 if(!buf_size)
2979 return win32_error_unicode("GetFinalPathNameByHandle", path);
2980
2981 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2982 if(!target_path)
2983 return PyErr_NoMemory();
2984
2985 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2986 buf_size, VOLUME_NAME_DOS);
2987 if(!result_length)
2988 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2989
2990 if(!CloseHandle(hFile))
2991 return win32_error_unicode("GetFinalPathNameByHandle", path);
2992
2993 target_path[result_length] = 0;
2994 result = PyUnicode_FromUnicode(target_path, result_length);
2995 free(target_path);
2996 return result;
2997
2998} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002999
3000static PyObject *
3001posix__getfileinformation(PyObject *self, PyObject *args)
3002{
3003 HANDLE hFile;
3004 BY_HANDLE_FILE_INFORMATION info;
3005 int fd;
3006
3007 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3008 return NULL;
3009
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003010 if (!_PyVerify_fd(fd))
3011 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003012
3013 hFile = (HANDLE)_get_osfhandle(fd);
3014 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003015 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003016
3017 if (!GetFileInformationByHandle(hFile, &info))
3018 return win32_error("_getfileinformation", NULL);
3019
3020 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3021 info.nFileIndexHigh,
3022 info.nFileIndexLow);
3023}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003024
Brian Curtin95d028f2011-06-09 09:10:38 -05003025PyDoc_STRVAR(posix__isdir__doc__,
3026"Return true if the pathname refers to an existing directory.");
3027
Brian Curtin9c669cc2011-06-08 18:17:18 -05003028static PyObject *
3029posix__isdir(PyObject *self, PyObject *args)
3030{
3031 PyObject *opath;
3032 char *path;
3033 PyUnicodeObject *po;
3034 DWORD attributes;
3035
3036 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
3037 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
3038
3039 attributes = GetFileAttributesW(wpath);
3040 if (attributes == INVALID_FILE_ATTRIBUTES)
3041 Py_RETURN_FALSE;
3042 goto check;
3043 }
3044 /* Drop the argument parsing error as narrow strings
3045 are also valid. */
3046 PyErr_Clear();
3047
3048 if (!PyArg_ParseTuple(args, "O&:_isdir",
3049 PyUnicode_FSConverter, &opath))
3050 return NULL;
3051
3052 path = PyBytes_AsString(opath);
3053 attributes = GetFileAttributesA(path);
3054 if (attributes == INVALID_FILE_ATTRIBUTES)
3055 Py_RETURN_FALSE;
3056
3057check:
3058 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3059 Py_RETURN_TRUE;
3060 else
3061 Py_RETURN_FALSE;
3062}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003063#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003064
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003065PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003066"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003067Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003068
Barry Warsaw53699e91996-12-10 23:23:01 +00003069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003070posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003071{
Victor Stinner8c62be82010-05-06 00:08:46 +00003072 int res;
3073 PyObject *opath;
3074 char *path;
3075 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003076
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003077#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003078 PyUnicodeObject *po;
3079 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
3080 Py_BEGIN_ALLOW_THREADS
3081 /* PyUnicode_AS_UNICODE OK without thread lock as
3082 it is a simple dereference. */
3083 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
3084 Py_END_ALLOW_THREADS
3085 if (!res)
3086 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
3087 Py_INCREF(Py_None);
3088 return Py_None;
3089 }
3090 /* Drop the argument parsing error as narrow strings
3091 are also valid. */
3092 PyErr_Clear();
3093 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
3094 PyUnicode_FSConverter, &opath, &mode))
3095 return NULL;
3096 path = PyBytes_AsString(opath);
3097 Py_BEGIN_ALLOW_THREADS
3098 /* PyUnicode_AS_UNICODE OK without thread lock as
3099 it is a simple dereference. */
3100 res = CreateDirectoryA(path, NULL);
3101 Py_END_ALLOW_THREADS
3102 if (!res) {
3103 win32_error("mkdir", path);
3104 Py_DECREF(opath);
3105 return NULL;
3106 }
3107 Py_DECREF(opath);
3108 Py_INCREF(Py_None);
3109 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003110#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003111
Victor Stinner8c62be82010-05-06 00:08:46 +00003112 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
3113 PyUnicode_FSConverter, &opath, &mode))
3114 return NULL;
3115 path = PyBytes_AsString(opath);
3116 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00003117#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00003118 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003119#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003120 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003121#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003122 Py_END_ALLOW_THREADS
3123 if (res < 0)
3124 return posix_error_with_allocated_filename(opath);
3125 Py_DECREF(opath);
3126 Py_INCREF(Py_None);
3127 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003128#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003129}
3130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003131
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003132/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3133#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003134#include <sys/resource.h>
3135#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003136
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003137
3138#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003139PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003140"nice(inc) -> new_priority\n\n\
3141Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003142
Barry Warsaw53699e91996-12-10 23:23:01 +00003143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003144posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003145{
Victor Stinner8c62be82010-05-06 00:08:46 +00003146 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003147
Victor Stinner8c62be82010-05-06 00:08:46 +00003148 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3149 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003150
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 /* There are two flavours of 'nice': one that returns the new
3152 priority (as required by almost all standards out there) and the
3153 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3154 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003155
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 If we are of the nice family that returns the new priority, we
3157 need to clear errno before the call, and check if errno is filled
3158 before calling posix_error() on a returnvalue of -1, because the
3159 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003160
Victor Stinner8c62be82010-05-06 00:08:46 +00003161 errno = 0;
3162 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003163#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003164 if (value == 0)
3165 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003166#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003167 if (value == -1 && errno != 0)
3168 /* either nice() or getpriority() returned an error */
3169 return posix_error();
3170 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003171}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003172#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003173
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003174
3175#ifdef HAVE_GETPRIORITY
3176PyDoc_STRVAR(posix_getpriority__doc__,
3177"getpriority(which, who) -> current_priority\n\n\
3178Get program scheduling priority.");
3179
3180static PyObject *
3181posix_getpriority(PyObject *self, PyObject *args)
3182{
3183 int which, who, retval;
3184
3185 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3186 return NULL;
3187 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003188 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003189 if (errno != 0)
3190 return posix_error();
3191 return PyLong_FromLong((long)retval);
3192}
3193#endif /* HAVE_GETPRIORITY */
3194
3195
3196#ifdef HAVE_SETPRIORITY
3197PyDoc_STRVAR(posix_setpriority__doc__,
3198"setpriority(which, who, prio) -> None\n\n\
3199Set program scheduling priority.");
3200
3201static PyObject *
3202posix_setpriority(PyObject *self, PyObject *args)
3203{
3204 int which, who, prio, retval;
3205
3206 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3207 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003208 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003209 if (retval == -1)
3210 return posix_error();
3211 Py_RETURN_NONE;
3212}
3213#endif /* HAVE_SETPRIORITY */
3214
3215
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003216PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003217"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003218Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003219
Barry Warsaw53699e91996-12-10 23:23:01 +00003220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003221posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003222{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003223#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 PyObject *o1, *o2;
3225 char *p1, *p2;
3226 BOOL result;
3227 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
3228 goto error;
3229 if (!convert_to_unicode(&o1))
3230 goto error;
3231 if (!convert_to_unicode(&o2)) {
3232 Py_DECREF(o1);
3233 goto error;
3234 }
3235 Py_BEGIN_ALLOW_THREADS
3236 result = MoveFileW(PyUnicode_AsUnicode(o1),
3237 PyUnicode_AsUnicode(o2));
3238 Py_END_ALLOW_THREADS
3239 Py_DECREF(o1);
3240 Py_DECREF(o2);
3241 if (!result)
3242 return win32_error("rename", NULL);
3243 Py_INCREF(Py_None);
3244 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003245error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003246 PyErr_Clear();
3247 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
3248 return NULL;
3249 Py_BEGIN_ALLOW_THREADS
3250 result = MoveFileA(p1, p2);
3251 Py_END_ALLOW_THREADS
3252 if (!result)
3253 return win32_error("rename", NULL);
3254 Py_INCREF(Py_None);
3255 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003256#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003258#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003259}
3260
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003261
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003262PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003263"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003264Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003265
Barry Warsaw53699e91996-12-10 23:23:01 +00003266static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003267posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003268{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003269#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003270 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003271#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003272 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003273#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003274}
3275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003277PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003278"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003279Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003280
Barry Warsaw53699e91996-12-10 23:23:01 +00003281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003282posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003283{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003284#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00003285 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003286#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003288#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003289}
3290
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003291
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003292#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003293PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003294"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003295Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003296
Barry Warsaw53699e91996-12-10 23:23:01 +00003297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003298posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003299{
Victor Stinner8c62be82010-05-06 00:08:46 +00003300 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003301#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003302 wchar_t *command;
3303 if (!PyArg_ParseTuple(args, "u:system", &command))
3304 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003305
Victor Stinner8c62be82010-05-06 00:08:46 +00003306 Py_BEGIN_ALLOW_THREADS
3307 sts = _wsystem(command);
3308 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003309#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003310 PyObject *command_obj;
3311 char *command;
3312 if (!PyArg_ParseTuple(args, "O&:system",
3313 PyUnicode_FSConverter, &command_obj))
3314 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003315
Victor Stinner8c62be82010-05-06 00:08:46 +00003316 command = PyBytes_AsString(command_obj);
3317 Py_BEGIN_ALLOW_THREADS
3318 sts = system(command);
3319 Py_END_ALLOW_THREADS
3320 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003321#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003322 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003323}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003324#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003326
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003327PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003328"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003329Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003330
Barry Warsaw53699e91996-12-10 23:23:01 +00003331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003332posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003333{
Victor Stinner8c62be82010-05-06 00:08:46 +00003334 int i;
3335 if (!PyArg_ParseTuple(args, "i:umask", &i))
3336 return NULL;
3337 i = (int)umask(i);
3338 if (i < 0)
3339 return posix_error();
3340 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003341}
3342
Brian Curtind40e6f72010-07-08 21:39:08 +00003343#ifdef MS_WINDOWS
3344
3345/* override the default DeleteFileW behavior so that directory
3346symlinks can be removed with this function, the same as with
3347Unix symlinks */
3348BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3349{
3350 WIN32_FILE_ATTRIBUTE_DATA info;
3351 WIN32_FIND_DATAW find_data;
3352 HANDLE find_data_handle;
3353 int is_directory = 0;
3354 int is_link = 0;
3355
3356 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3357 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003358
Brian Curtind40e6f72010-07-08 21:39:08 +00003359 /* Get WIN32_FIND_DATA structure for the path to determine if
3360 it is a symlink */
3361 if(is_directory &&
3362 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3363 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3364
3365 if(find_data_handle != INVALID_HANDLE_VALUE) {
3366 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3367 FindClose(find_data_handle);
3368 }
3369 }
3370 }
3371
3372 if (is_directory && is_link)
3373 return RemoveDirectoryW(lpFileName);
3374
3375 return DeleteFileW(lpFileName);
3376}
3377#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003378
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003379PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003380"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003381Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003383PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003384"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003385Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003386
Barry Warsaw53699e91996-12-10 23:23:01 +00003387static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003388posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003389{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003390#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003391 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3392 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003393#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003394 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003395#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003396}
3397
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003398
Guido van Rossumb6775db1994-08-01 11:34:53 +00003399#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003400PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003401"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003402Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003403
Barry Warsaw53699e91996-12-10 23:23:01 +00003404static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003405posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003406{
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 struct utsname u;
3408 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003409
Victor Stinner8c62be82010-05-06 00:08:46 +00003410 Py_BEGIN_ALLOW_THREADS
3411 res = uname(&u);
3412 Py_END_ALLOW_THREADS
3413 if (res < 0)
3414 return posix_error();
3415 return Py_BuildValue("(sssss)",
3416 u.sysname,
3417 u.nodename,
3418 u.release,
3419 u.version,
3420 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003421}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003422#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003423
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003424
3425/*
3426 * Classic POSIX utime functions supported microseconds (1m/sec).
3427 * Newer POSIX functions support nanoseconds (1 billion per sec).
3428 * posixmodule now uses the new functions where possible.
3429 * This improves accuracy in many situations, for example shutil.copy2().
3430 *
3431 * The implementation isn't currently sophisticated enough to handle
3432 * a platform where HAVE_UTIMENSAT is true but HAVE_FUTIMENS is false.
3433 * Specifically, posix_futimes() would break.
3434 *
3435 * Supporting such a platform wouldn't be impossible; you'd need two
3436 * extract_time() functions, or make its precision a parameter.
3437 * Since such a platform seems unlikely we haven't bothered.
3438 */
3439#if defined(HAVE_UTIMENSAT)
3440#define EXTRACT_TIME_PRECISION (1e9)
3441#if !defined(HAVE_FUTIMENS)
3442#error You HAVE_UTIMENSAT but not HAVE_FUTIMENS... please see accompanying comment.
3443#endif
3444#else
3445#define EXTRACT_TIME_PRECISION (1e6)
3446#endif
3447
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003448static int
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003449extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003450{
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003451 time_t intval;
Victor Stinner8c62be82010-05-06 00:08:46 +00003452 if (PyFloat_Check(t)) {
3453 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003454 PyObject *intobj = PyNumber_Long(t);
Victor Stinner8c62be82010-05-06 00:08:46 +00003455 if (!intobj)
3456 return -1;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003457#if SIZEOF_TIME_T > SIZEOF_LONG
3458 intval = PyLong_AsUnsignedLongLongMask(intobj);
3459#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 intval = PyLong_AsLong(intobj);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003461#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003462 Py_DECREF(intobj);
3463 if (intval == -1 && PyErr_Occurred())
3464 return -1;
3465 *sec = intval;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003466
3467 *usec = (long)((tval - intval) * EXTRACT_TIME_PRECISION);
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 if (*usec < 0)
3469 /* If rounding gave us a negative number,
3470 truncate. */
3471 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003472 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003473 }
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003474#if SIZEOF_TIME_T > SIZEOF_LONG
3475 intval = PyLong_AsUnsignedLongLongMask(t);
3476#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003477 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003478#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003479 if (intval == -1 && PyErr_Occurred())
3480 return -1;
3481 *sec = intval;
3482 *usec = 0;
3483 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003484}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003485
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003486PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003487"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003488utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003489Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003490second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003491
Barry Warsaw53699e91996-12-10 23:23:01 +00003492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003493posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003494{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003495#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003496 PyObject *arg;
3497 PyUnicodeObject *obwpath;
3498 wchar_t *wpath = NULL;
3499 PyObject *oapath;
3500 char *apath;
3501 HANDLE hFile;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003502 time_t atimesec, mtimesec;
3503 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 FILETIME atime, mtime;
3505 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003506
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3508 wpath = PyUnicode_AS_UNICODE(obwpath);
3509 Py_BEGIN_ALLOW_THREADS
3510 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3511 NULL, OPEN_EXISTING,
3512 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3513 Py_END_ALLOW_THREADS
3514 if (hFile == INVALID_HANDLE_VALUE)
3515 return win32_error_unicode("utime", wpath);
3516 } else
3517 /* Drop the argument parsing error as narrow strings
3518 are also valid. */
3519 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003520
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 if (!wpath) {
3522 if (!PyArg_ParseTuple(args, "O&O:utime",
3523 PyUnicode_FSConverter, &oapath, &arg))
3524 return NULL;
3525 apath = PyBytes_AsString(oapath);
3526 Py_BEGIN_ALLOW_THREADS
3527 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3528 NULL, OPEN_EXISTING,
3529 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3530 Py_END_ALLOW_THREADS
3531 if (hFile == INVALID_HANDLE_VALUE) {
3532 win32_error("utime", apath);
3533 Py_DECREF(oapath);
3534 return NULL;
3535 }
3536 Py_DECREF(oapath);
3537 }
3538
3539 if (arg == Py_None) {
3540 SYSTEMTIME now;
3541 GetSystemTime(&now);
3542 if (!SystemTimeToFileTime(&now, &mtime) ||
3543 !SystemTimeToFileTime(&now, &atime)) {
3544 win32_error("utime", NULL);
3545 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003546 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 }
3548 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3549 PyErr_SetString(PyExc_TypeError,
3550 "utime() arg 2 must be a tuple (atime, mtime)");
3551 goto done;
3552 }
3553 else {
3554 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3555 &atimesec, &ausec) == -1)
3556 goto done;
3557 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3558 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3559 &mtimesec, &musec) == -1)
3560 goto done;
3561 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3562 }
3563 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3564 /* Avoid putting the file name into the error here,
3565 as that may confuse the user into believing that
3566 something is wrong with the file, when it also
3567 could be the time stamp that gives a problem. */
3568 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003569 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 }
3571 Py_INCREF(Py_None);
3572 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003573done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 CloseHandle(hFile);
3575 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003576#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003577
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 PyObject *opath;
3579 char *path;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003580 time_t atime, mtime;
3581 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 int res;
3583 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003584
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 if (!PyArg_ParseTuple(args, "O&O:utime",
3586 PyUnicode_FSConverter, &opath, &arg))
3587 return NULL;
3588 path = PyBytes_AsString(opath);
3589 if (arg == Py_None) {
3590 /* optional time values not given */
3591 Py_BEGIN_ALLOW_THREADS
3592 res = utime(path, NULL);
3593 Py_END_ALLOW_THREADS
3594 }
3595 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3596 PyErr_SetString(PyExc_TypeError,
3597 "utime() arg 2 must be a tuple (atime, mtime)");
3598 Py_DECREF(opath);
3599 return NULL;
3600 }
3601 else {
3602 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3603 &atime, &ausec) == -1) {
3604 Py_DECREF(opath);
3605 return NULL;
3606 }
3607 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3608 &mtime, &musec) == -1) {
3609 Py_DECREF(opath);
3610 return NULL;
3611 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003612
3613 Py_BEGIN_ALLOW_THREADS
3614 {
3615#ifdef HAVE_UTIMENSAT
3616 struct timespec buf[2];
3617 buf[0].tv_sec = atime;
3618 buf[0].tv_nsec = ausec;
3619 buf[1].tv_sec = mtime;
3620 buf[1].tv_nsec = musec;
3621 res = utimensat(AT_FDCWD, path, buf, 0);
3622#elif defined(HAVE_UTIMES)
3623 struct timeval buf[2];
3624 buf[0].tv_sec = atime;
Victor Stinner8c62be82010-05-06 00:08:46 +00003625 buf[0].tv_usec = ausec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003626 buf[1].tv_sec = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 buf[1].tv_usec = musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 res = utimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003629#elif defined(HAVE_UTIME_H)
3630 /* XXX should define struct utimbuf instead, above */
3631 struct utimbuf buf;
3632 buf.actime = atime;
3633 buf.modtime = mtime;
3634 res = utime(path, &buf);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003635#else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003636 time_t buf[2];
3637 buf[0] = atime;
3638 buf[1] = mtime;
3639 res = utime(path, buf);
3640#endif
3641 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003642 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 }
3644 if (res < 0) {
3645 return posix_error_with_allocated_filename(opath);
3646 }
3647 Py_DECREF(opath);
3648 Py_INCREF(Py_None);
3649 return Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003650#undef UTIME_EXTRACT
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003651#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003652}
3653
Ross Lagerwall7807c352011-03-17 20:20:30 +02003654#ifdef HAVE_FUTIMES
3655PyDoc_STRVAR(posix_futimes__doc__,
3656"futimes(fd, (atime, mtime))\n\
3657futimes(fd, None)\n\n\
3658Set the access and modified time of the file specified by the file\n\
3659descriptor fd to the given values. If the second form is used, set the\n\
3660access and modified times to the current time.");
3661
3662static PyObject *
3663posix_futimes(PyObject *self, PyObject *args)
3664{
3665 int res, fd;
3666 PyObject* arg;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003667 time_t atime, mtime;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003668 long ausec, musec;
3669
3670 if (!PyArg_ParseTuple(args, "iO:futimes", &fd, &arg))
3671 return NULL;
3672
3673 if (arg == Py_None) {
3674 /* optional time values not given */
3675 Py_BEGIN_ALLOW_THREADS
3676 res = futimes(fd, NULL);
3677 Py_END_ALLOW_THREADS
3678 }
3679 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3680 PyErr_SetString(PyExc_TypeError,
3681 "futimes() arg 2 must be a tuple (atime, mtime)");
3682 return NULL;
3683 }
3684 else {
3685 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003686 &atime, &ausec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003687 return NULL;
3688 }
3689 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003690 &mtime, &musec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003691 return NULL;
3692 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003693 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003694 {
3695#ifdef HAVE_FUTIMENS
3696 struct timespec buf[2];
3697 buf[0].tv_sec = atime;
3698 buf[0].tv_nsec = ausec;
3699 buf[1].tv_sec = mtime;
3700 buf[1].tv_nsec = musec;
3701 res = futimens(fd, buf);
3702#else
3703 struct timeval buf[2];
3704 buf[0].tv_sec = atime;
3705 buf[0].tv_usec = ausec;
3706 buf[1].tv_sec = mtime;
3707 buf[1].tv_usec = musec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003708 res = futimes(fd, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003709#endif
3710 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003711 Py_END_ALLOW_THREADS
3712 }
3713 if (res < 0)
3714 return posix_error();
3715 Py_RETURN_NONE;
3716}
3717#endif
3718
3719#ifdef HAVE_LUTIMES
3720PyDoc_STRVAR(posix_lutimes__doc__,
3721"lutimes(path, (atime, mtime))\n\
3722lutimes(path, None)\n\n\
3723Like utime(), but if path is a symbolic link, it is not dereferenced.");
3724
3725static PyObject *
3726posix_lutimes(PyObject *self, PyObject *args)
3727{
3728 PyObject *opath, *arg;
3729 const char *path;
3730 int res;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003731 time_t atime, mtime;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003732 long ausec, musec;
3733
3734 if (!PyArg_ParseTuple(args, "O&O:lutimes",
3735 PyUnicode_FSConverter, &opath, &arg))
3736 return NULL;
3737 path = PyBytes_AsString(opath);
3738 if (arg == Py_None) {
3739 /* optional time values not given */
3740 Py_BEGIN_ALLOW_THREADS
3741 res = lutimes(path, NULL);
3742 Py_END_ALLOW_THREADS
3743 }
3744 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3745 PyErr_SetString(PyExc_TypeError,
3746 "lutimes() arg 2 must be a tuple (atime, mtime)");
3747 Py_DECREF(opath);
3748 return NULL;
3749 }
3750 else {
3751 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003752 &atime, &ausec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003753 Py_DECREF(opath);
3754 return NULL;
3755 }
3756 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003757 &mtime, &musec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003758 Py_DECREF(opath);
3759 return NULL;
3760 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003761 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003762 {
3763#ifdef HAVE_UTIMENSAT
3764 struct timespec buf[2];
3765 buf[0].tv_sec = atime;
3766 buf[0].tv_nsec = ausec;
3767 buf[1].tv_sec = mtime;
3768 buf[1].tv_nsec = musec;
3769 res = utimensat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
3770#else
3771 struct timeval buf[2];
3772 buf[0].tv_sec = atime;
3773 buf[0].tv_usec = ausec;
3774 buf[1].tv_sec = mtime;
3775 buf[1].tv_usec = musec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003776 res = lutimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003777#endif
3778 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003779 Py_END_ALLOW_THREADS
3780 }
3781 Py_DECREF(opath);
3782 if (res < 0)
3783 return posix_error();
3784 Py_RETURN_NONE;
3785}
3786#endif
3787
3788#ifdef HAVE_FUTIMENS
3789PyDoc_STRVAR(posix_futimens__doc__,
3790"futimens(fd, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec))\n\
3791futimens(fd, None, None)\n\n\
3792Updates the timestamps of a file specified by the file descriptor fd, with\n\
3793nanosecond precision.\n\
3794The second form sets atime and mtime to the current time.\n\
3795If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
3796current time.\n\
3797If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
3798
3799static PyObject *
3800posix_futimens(PyObject *self, PyObject *args)
3801{
3802 int res, fd;
3803 PyObject *atime, *mtime;
3804 struct timespec buf[2];
3805
3806 if (!PyArg_ParseTuple(args, "iOO:futimens",
3807 &fd, &atime, &mtime))
3808 return NULL;
3809 if (atime == Py_None && mtime == Py_None) {
3810 /* optional time values not given */
3811 Py_BEGIN_ALLOW_THREADS
3812 res = futimens(fd, NULL);
3813 Py_END_ALLOW_THREADS
3814 }
3815 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
3816 PyErr_SetString(PyExc_TypeError,
3817 "futimens() arg 2 must be a tuple (atime_sec, atime_nsec)");
3818 return NULL;
3819 }
3820 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
3821 PyErr_SetString(PyExc_TypeError,
3822 "futimens() arg 3 must be a tuple (mtime_sec, mtime_nsec)");
3823 return NULL;
3824 }
3825 else {
3826 if (!PyArg_ParseTuple(atime, "ll:futimens",
3827 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
3828 return NULL;
3829 }
3830 if (!PyArg_ParseTuple(mtime, "ll:futimens",
3831 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
3832 return NULL;
3833 }
3834 Py_BEGIN_ALLOW_THREADS
3835 res = futimens(fd, buf);
3836 Py_END_ALLOW_THREADS
3837 }
3838 if (res < 0)
3839 return posix_error();
3840 Py_RETURN_NONE;
3841}
3842#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003843
Guido van Rossum3b066191991-06-04 19:40:25 +00003844/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003845
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003846PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003847"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003848Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003849
Barry Warsaw53699e91996-12-10 23:23:01 +00003850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003851posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003852{
Victor Stinner8c62be82010-05-06 00:08:46 +00003853 int sts;
3854 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3855 return NULL;
3856 _exit(sts);
3857 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003858}
3859
Martin v. Löwis114619e2002-10-07 06:44:21 +00003860#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3861static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003862free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003863{
Victor Stinner8c62be82010-05-06 00:08:46 +00003864 Py_ssize_t i;
3865 for (i = 0; i < count; i++)
3866 PyMem_Free(array[i]);
3867 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003868}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003869
Antoine Pitrou69f71142009-05-24 21:25:49 +00003870static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003871int fsconvert_strdup(PyObject *o, char**out)
3872{
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 PyObject *bytes;
3874 Py_ssize_t size;
3875 if (!PyUnicode_FSConverter(o, &bytes))
3876 return 0;
3877 size = PyBytes_GET_SIZE(bytes);
3878 *out = PyMem_Malloc(size+1);
3879 if (!*out)
3880 return 0;
3881 memcpy(*out, PyBytes_AsString(bytes), size+1);
3882 Py_DECREF(bytes);
3883 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003884}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003885#endif
3886
Ross Lagerwall7807c352011-03-17 20:20:30 +02003887#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00003888static char**
3889parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3890{
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 char **envlist;
3892 Py_ssize_t i, pos, envc;
3893 PyObject *keys=NULL, *vals=NULL;
3894 PyObject *key, *val, *key2, *val2;
3895 char *p, *k, *v;
3896 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003897
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 i = PyMapping_Size(env);
3899 if (i < 0)
3900 return NULL;
3901 envlist = PyMem_NEW(char *, i + 1);
3902 if (envlist == NULL) {
3903 PyErr_NoMemory();
3904 return NULL;
3905 }
3906 envc = 0;
3907 keys = PyMapping_Keys(env);
3908 vals = PyMapping_Values(env);
3909 if (!keys || !vals)
3910 goto error;
3911 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3912 PyErr_Format(PyExc_TypeError,
3913 "env.keys() or env.values() is not a list");
3914 goto error;
3915 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003916
Victor Stinner8c62be82010-05-06 00:08:46 +00003917 for (pos = 0; pos < i; pos++) {
3918 key = PyList_GetItem(keys, pos);
3919 val = PyList_GetItem(vals, pos);
3920 if (!key || !val)
3921 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003922
Victor Stinner8c62be82010-05-06 00:08:46 +00003923 if (PyUnicode_FSConverter(key, &key2) == 0)
3924 goto error;
3925 if (PyUnicode_FSConverter(val, &val2) == 0) {
3926 Py_DECREF(key2);
3927 goto error;
3928 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003929
3930#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003931 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3932 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003933#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003934 k = PyBytes_AsString(key2);
3935 v = PyBytes_AsString(val2);
3936 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003937
Victor Stinner8c62be82010-05-06 00:08:46 +00003938 p = PyMem_NEW(char, len);
3939 if (p == NULL) {
3940 PyErr_NoMemory();
3941 Py_DECREF(key2);
3942 Py_DECREF(val2);
3943 goto error;
3944 }
3945 PyOS_snprintf(p, len, "%s=%s", k, v);
3946 envlist[envc++] = p;
3947 Py_DECREF(key2);
3948 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003949#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003950 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003951#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 }
3953 Py_DECREF(vals);
3954 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003955
Victor Stinner8c62be82010-05-06 00:08:46 +00003956 envlist[envc] = 0;
3957 *envc_ptr = envc;
3958 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003959
3960error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 Py_XDECREF(keys);
3962 Py_XDECREF(vals);
3963 while (--envc >= 0)
3964 PyMem_DEL(envlist[envc]);
3965 PyMem_DEL(envlist);
3966 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003967}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003968
Ross Lagerwall7807c352011-03-17 20:20:30 +02003969static char**
3970parse_arglist(PyObject* argv, Py_ssize_t *argc)
3971{
3972 int i;
3973 char **argvlist = PyMem_NEW(char *, *argc+1);
3974 if (argvlist == NULL) {
3975 PyErr_NoMemory();
3976 return NULL;
3977 }
3978 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02003979 PyObject* item = PySequence_ITEM(argv, i);
3980 if (item == NULL)
3981 goto fail;
3982 if (!fsconvert_strdup(item, &argvlist[i])) {
3983 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02003984 goto fail;
3985 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02003986 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02003987 }
3988 argvlist[*argc] = NULL;
3989 return argvlist;
3990fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02003991 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003992 free_string_array(argvlist, *argc);
3993 return NULL;
3994}
3995#endif
3996
3997#ifdef HAVE_EXECV
3998PyDoc_STRVAR(posix_execv__doc__,
3999"execv(path, args)\n\n\
4000Execute an executable path with arguments, replacing current process.\n\
4001\n\
4002 path: path of executable file\n\
4003 args: tuple or list of strings");
4004
4005static PyObject *
4006posix_execv(PyObject *self, PyObject *args)
4007{
4008 PyObject *opath;
4009 char *path;
4010 PyObject *argv;
4011 char **argvlist;
4012 Py_ssize_t argc;
4013
4014 /* execv has two arguments: (path, argv), where
4015 argv is a list or tuple of strings. */
4016
4017 if (!PyArg_ParseTuple(args, "O&O:execv",
4018 PyUnicode_FSConverter,
4019 &opath, &argv))
4020 return NULL;
4021 path = PyBytes_AsString(opath);
4022 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4023 PyErr_SetString(PyExc_TypeError,
4024 "execv() arg 2 must be a tuple or list");
4025 Py_DECREF(opath);
4026 return NULL;
4027 }
4028 argc = PySequence_Size(argv);
4029 if (argc < 1) {
4030 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4031 Py_DECREF(opath);
4032 return NULL;
4033 }
4034
4035 argvlist = parse_arglist(argv, &argc);
4036 if (argvlist == NULL) {
4037 Py_DECREF(opath);
4038 return NULL;
4039 }
4040
4041 execv(path, argvlist);
4042
4043 /* If we get here it's definitely an error */
4044
4045 free_string_array(argvlist, argc);
4046 Py_DECREF(opath);
4047 return posix_error();
4048}
4049
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004050PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004051"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004052Execute a path with arguments and environment, replacing current process.\n\
4053\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004054 path: path of executable file\n\
4055 args: tuple or list of arguments\n\
4056 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004057
Barry Warsaw53699e91996-12-10 23:23:01 +00004058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004059posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004060{
Victor Stinner8c62be82010-05-06 00:08:46 +00004061 PyObject *opath;
4062 char *path;
4063 PyObject *argv, *env;
4064 char **argvlist;
4065 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004066 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004067
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 /* execve has three arguments: (path, argv, env), where
4069 argv is a list or tuple of strings and env is a dictionary
4070 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004071
Victor Stinner8c62be82010-05-06 00:08:46 +00004072 if (!PyArg_ParseTuple(args, "O&OO:execve",
4073 PyUnicode_FSConverter,
4074 &opath, &argv, &env))
4075 return NULL;
4076 path = PyBytes_AsString(opath);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004077 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004078 PyErr_SetString(PyExc_TypeError,
4079 "execve() arg 2 must be a tuple or list");
4080 goto fail_0;
4081 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004082 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004083 if (!PyMapping_Check(env)) {
4084 PyErr_SetString(PyExc_TypeError,
4085 "execve() arg 3 must be a mapping object");
4086 goto fail_0;
4087 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004088
Ross Lagerwall7807c352011-03-17 20:20:30 +02004089 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004090 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004091 goto fail_0;
4092 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004093
Victor Stinner8c62be82010-05-06 00:08:46 +00004094 envlist = parse_envlist(env, &envc);
4095 if (envlist == NULL)
4096 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004097
Victor Stinner8c62be82010-05-06 00:08:46 +00004098 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00004099
Victor Stinner8c62be82010-05-06 00:08:46 +00004100 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004101
Victor Stinner8c62be82010-05-06 00:08:46 +00004102 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004103
Victor Stinner8c62be82010-05-06 00:08:46 +00004104 while (--envc >= 0)
4105 PyMem_DEL(envlist[envc]);
4106 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004107 fail_1:
Ross Lagerwall7807c352011-03-17 20:20:30 +02004108 free_string_array(argvlist, argc);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004109 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004110 Py_DECREF(opath);
4111 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004112}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004113#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004114
Ross Lagerwall7807c352011-03-17 20:20:30 +02004115#ifdef HAVE_FEXECVE
4116PyDoc_STRVAR(posix_fexecve__doc__,
4117"fexecve(fd, args, env)\n\n\
4118Execute the program specified by a file descriptor with arguments and\n\
4119environment, replacing the current process.\n\
4120\n\
4121 fd: file descriptor of executable\n\
4122 args: tuple or list of arguments\n\
4123 env: dictionary of strings mapping to strings");
4124
4125static PyObject *
4126posix_fexecve(PyObject *self, PyObject *args)
4127{
4128 int fd;
4129 PyObject *argv, *env;
4130 char **argvlist;
4131 char **envlist;
4132 Py_ssize_t argc, envc;
4133
4134 if (!PyArg_ParseTuple(args, "iOO:fexecve",
4135 &fd, &argv, &env))
4136 return NULL;
4137 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4138 PyErr_SetString(PyExc_TypeError,
4139 "fexecve() arg 2 must be a tuple or list");
4140 return NULL;
4141 }
4142 argc = PySequence_Size(argv);
4143 if (!PyMapping_Check(env)) {
4144 PyErr_SetString(PyExc_TypeError,
4145 "fexecve() arg 3 must be a mapping object");
4146 return NULL;
4147 }
4148
4149 argvlist = parse_arglist(argv, &argc);
4150 if (argvlist == NULL)
4151 return NULL;
4152
4153 envlist = parse_envlist(env, &envc);
4154 if (envlist == NULL)
4155 goto fail;
4156
4157 fexecve(fd, argvlist, envlist);
4158
4159 /* If we get here it's definitely an error */
4160
4161 (void) posix_error();
4162
4163 while (--envc >= 0)
4164 PyMem_DEL(envlist[envc]);
4165 PyMem_DEL(envlist);
4166 fail:
4167 free_string_array(argvlist, argc);
4168 return NULL;
4169}
4170#endif /* HAVE_FEXECVE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004171
Guido van Rossuma1065681999-01-25 23:20:23 +00004172#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004173PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004174"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004175Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004176\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004177 mode: mode of process creation\n\
4178 path: path of executable file\n\
4179 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004180
4181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004182posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004183{
Victor Stinner8c62be82010-05-06 00:08:46 +00004184 PyObject *opath;
4185 char *path;
4186 PyObject *argv;
4187 char **argvlist;
4188 int mode, i;
4189 Py_ssize_t argc;
4190 Py_intptr_t spawnval;
4191 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004192
Victor Stinner8c62be82010-05-06 00:08:46 +00004193 /* spawnv has three arguments: (mode, path, argv), where
4194 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004195
Victor Stinner8c62be82010-05-06 00:08:46 +00004196 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4197 PyUnicode_FSConverter,
4198 &opath, &argv))
4199 return NULL;
4200 path = PyBytes_AsString(opath);
4201 if (PyList_Check(argv)) {
4202 argc = PyList_Size(argv);
4203 getitem = PyList_GetItem;
4204 }
4205 else if (PyTuple_Check(argv)) {
4206 argc = PyTuple_Size(argv);
4207 getitem = PyTuple_GetItem;
4208 }
4209 else {
4210 PyErr_SetString(PyExc_TypeError,
4211 "spawnv() arg 2 must be a tuple or list");
4212 Py_DECREF(opath);
4213 return NULL;
4214 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004215
Victor Stinner8c62be82010-05-06 00:08:46 +00004216 argvlist = PyMem_NEW(char *, argc+1);
4217 if (argvlist == NULL) {
4218 Py_DECREF(opath);
4219 return PyErr_NoMemory();
4220 }
4221 for (i = 0; i < argc; i++) {
4222 if (!fsconvert_strdup((*getitem)(argv, i),
4223 &argvlist[i])) {
4224 free_string_array(argvlist, i);
4225 PyErr_SetString(
4226 PyExc_TypeError,
4227 "spawnv() arg 2 must contain only strings");
4228 Py_DECREF(opath);
4229 return NULL;
4230 }
4231 }
4232 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004233
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004234#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004235 Py_BEGIN_ALLOW_THREADS
4236 spawnval = spawnv(mode, path, argvlist);
4237 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004238#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004239 if (mode == _OLD_P_OVERLAY)
4240 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004241
Victor Stinner8c62be82010-05-06 00:08:46 +00004242 Py_BEGIN_ALLOW_THREADS
4243 spawnval = _spawnv(mode, path, argvlist);
4244 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004245#endif
Tim Peters5aa91602002-01-30 05:46:57 +00004246
Victor Stinner8c62be82010-05-06 00:08:46 +00004247 free_string_array(argvlist, argc);
4248 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004249
Victor Stinner8c62be82010-05-06 00:08:46 +00004250 if (spawnval == -1)
4251 return posix_error();
4252 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004253#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004254 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004255#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004256 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004257#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004258}
4259
4260
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004261PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004262"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004263Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004264\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004265 mode: mode of process creation\n\
4266 path: path of executable file\n\
4267 args: tuple or list of arguments\n\
4268 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004269
4270static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004271posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004272{
Victor Stinner8c62be82010-05-06 00:08:46 +00004273 PyObject *opath;
4274 char *path;
4275 PyObject *argv, *env;
4276 char **argvlist;
4277 char **envlist;
4278 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004279 int mode;
4280 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004281 Py_intptr_t spawnval;
4282 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4283 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004284
Victor Stinner8c62be82010-05-06 00:08:46 +00004285 /* spawnve has four arguments: (mode, path, argv, env), where
4286 argv is a list or tuple of strings and env is a dictionary
4287 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004288
Victor Stinner8c62be82010-05-06 00:08:46 +00004289 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4290 PyUnicode_FSConverter,
4291 &opath, &argv, &env))
4292 return NULL;
4293 path = PyBytes_AsString(opath);
4294 if (PyList_Check(argv)) {
4295 argc = PyList_Size(argv);
4296 getitem = PyList_GetItem;
4297 }
4298 else if (PyTuple_Check(argv)) {
4299 argc = PyTuple_Size(argv);
4300 getitem = PyTuple_GetItem;
4301 }
4302 else {
4303 PyErr_SetString(PyExc_TypeError,
4304 "spawnve() arg 2 must be a tuple or list");
4305 goto fail_0;
4306 }
4307 if (!PyMapping_Check(env)) {
4308 PyErr_SetString(PyExc_TypeError,
4309 "spawnve() arg 3 must be a mapping object");
4310 goto fail_0;
4311 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004312
Victor Stinner8c62be82010-05-06 00:08:46 +00004313 argvlist = PyMem_NEW(char *, argc+1);
4314 if (argvlist == NULL) {
4315 PyErr_NoMemory();
4316 goto fail_0;
4317 }
4318 for (i = 0; i < argc; i++) {
4319 if (!fsconvert_strdup((*getitem)(argv, i),
4320 &argvlist[i]))
4321 {
4322 lastarg = i;
4323 goto fail_1;
4324 }
4325 }
4326 lastarg = argc;
4327 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004328
Victor Stinner8c62be82010-05-06 00:08:46 +00004329 envlist = parse_envlist(env, &envc);
4330 if (envlist == NULL)
4331 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004332
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004333#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004334 Py_BEGIN_ALLOW_THREADS
4335 spawnval = spawnve(mode, path, argvlist, envlist);
4336 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004337#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004338 if (mode == _OLD_P_OVERLAY)
4339 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004340
Victor Stinner8c62be82010-05-06 00:08:46 +00004341 Py_BEGIN_ALLOW_THREADS
4342 spawnval = _spawnve(mode, path, argvlist, envlist);
4343 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004344#endif
Tim Peters25059d32001-12-07 20:35:43 +00004345
Victor Stinner8c62be82010-05-06 00:08:46 +00004346 if (spawnval == -1)
4347 (void) posix_error();
4348 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004349#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004350 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004351#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004352 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004353#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004354
Victor Stinner8c62be82010-05-06 00:08:46 +00004355 while (--envc >= 0)
4356 PyMem_DEL(envlist[envc]);
4357 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004358 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004359 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004360 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004361 Py_DECREF(opath);
4362 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004363}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004364
4365/* OS/2 supports spawnvp & spawnvpe natively */
4366#if defined(PYOS_OS2)
4367PyDoc_STRVAR(posix_spawnvp__doc__,
4368"spawnvp(mode, file, args)\n\n\
4369Execute the program 'file' in a new process, using the environment\n\
4370search path to find the file.\n\
4371\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004372 mode: mode of process creation\n\
4373 file: executable file name\n\
4374 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004375
4376static PyObject *
4377posix_spawnvp(PyObject *self, PyObject *args)
4378{
Victor Stinner8c62be82010-05-06 00:08:46 +00004379 PyObject *opath;
4380 char *path;
4381 PyObject *argv;
4382 char **argvlist;
4383 int mode, i, argc;
4384 Py_intptr_t spawnval;
4385 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004386
Victor Stinner8c62be82010-05-06 00:08:46 +00004387 /* spawnvp has three arguments: (mode, path, argv), where
4388 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004389
Victor Stinner8c62be82010-05-06 00:08:46 +00004390 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
4391 PyUnicode_FSConverter,
4392 &opath, &argv))
4393 return NULL;
4394 path = PyBytes_AsString(opath);
4395 if (PyList_Check(argv)) {
4396 argc = PyList_Size(argv);
4397 getitem = PyList_GetItem;
4398 }
4399 else if (PyTuple_Check(argv)) {
4400 argc = PyTuple_Size(argv);
4401 getitem = PyTuple_GetItem;
4402 }
4403 else {
4404 PyErr_SetString(PyExc_TypeError,
4405 "spawnvp() arg 2 must be a tuple or list");
4406 Py_DECREF(opath);
4407 return NULL;
4408 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004409
Victor Stinner8c62be82010-05-06 00:08:46 +00004410 argvlist = PyMem_NEW(char *, argc+1);
4411 if (argvlist == NULL) {
4412 Py_DECREF(opath);
4413 return PyErr_NoMemory();
4414 }
4415 for (i = 0; i < argc; i++) {
4416 if (!fsconvert_strdup((*getitem)(argv, i),
4417 &argvlist[i])) {
4418 free_string_array(argvlist, i);
4419 PyErr_SetString(
4420 PyExc_TypeError,
4421 "spawnvp() arg 2 must contain only strings");
4422 Py_DECREF(opath);
4423 return NULL;
4424 }
4425 }
4426 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004427
Victor Stinner8c62be82010-05-06 00:08:46 +00004428 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004429#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004430 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004431#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004432 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004433#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004434 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004435
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 free_string_array(argvlist, argc);
4437 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004438
Victor Stinner8c62be82010-05-06 00:08:46 +00004439 if (spawnval == -1)
4440 return posix_error();
4441 else
4442 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004443}
4444
4445
4446PyDoc_STRVAR(posix_spawnvpe__doc__,
4447"spawnvpe(mode, file, args, env)\n\n\
4448Execute the program 'file' in a new process, using the environment\n\
4449search path to find the file.\n\
4450\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004451 mode: mode of process creation\n\
4452 file: executable file name\n\
4453 args: tuple or list of arguments\n\
4454 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004455
4456static PyObject *
4457posix_spawnvpe(PyObject *self, PyObject *args)
4458{
Victor Stinner8c62be82010-05-06 00:08:46 +00004459 PyObject *opath
4460 char *path;
4461 PyObject *argv, *env;
4462 char **argvlist;
4463 char **envlist;
4464 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004465 int mode;
4466 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004467 Py_intptr_t spawnval;
4468 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4469 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004470
Victor Stinner8c62be82010-05-06 00:08:46 +00004471 /* spawnvpe has four arguments: (mode, path, argv, env), where
4472 argv is a list or tuple of strings and env is a dictionary
4473 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004474
Victor Stinner8c62be82010-05-06 00:08:46 +00004475 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4476 PyUnicode_FSConverter,
4477 &opath, &argv, &env))
4478 return NULL;
4479 path = PyBytes_AsString(opath);
4480 if (PyList_Check(argv)) {
4481 argc = PyList_Size(argv);
4482 getitem = PyList_GetItem;
4483 }
4484 else if (PyTuple_Check(argv)) {
4485 argc = PyTuple_Size(argv);
4486 getitem = PyTuple_GetItem;
4487 }
4488 else {
4489 PyErr_SetString(PyExc_TypeError,
4490 "spawnvpe() arg 2 must be a tuple or list");
4491 goto fail_0;
4492 }
4493 if (!PyMapping_Check(env)) {
4494 PyErr_SetString(PyExc_TypeError,
4495 "spawnvpe() arg 3 must be a mapping object");
4496 goto fail_0;
4497 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004498
Victor Stinner8c62be82010-05-06 00:08:46 +00004499 argvlist = PyMem_NEW(char *, argc+1);
4500 if (argvlist == NULL) {
4501 PyErr_NoMemory();
4502 goto fail_0;
4503 }
4504 for (i = 0; i < argc; i++) {
4505 if (!fsconvert_strdup((*getitem)(argv, i),
4506 &argvlist[i]))
4507 {
4508 lastarg = i;
4509 goto fail_1;
4510 }
4511 }
4512 lastarg = argc;
4513 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004514
Victor Stinner8c62be82010-05-06 00:08:46 +00004515 envlist = parse_envlist(env, &envc);
4516 if (envlist == NULL)
4517 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004518
Victor Stinner8c62be82010-05-06 00:08:46 +00004519 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004520#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004521 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004522#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004523 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004524#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004525 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004526
Victor Stinner8c62be82010-05-06 00:08:46 +00004527 if (spawnval == -1)
4528 (void) posix_error();
4529 else
4530 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004531
Victor Stinner8c62be82010-05-06 00:08:46 +00004532 while (--envc >= 0)
4533 PyMem_DEL(envlist[envc]);
4534 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004535 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004536 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004537 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004538 Py_DECREF(opath);
4539 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004540}
4541#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004542#endif /* HAVE_SPAWNV */
4543
4544
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004545#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004546PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004547"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004548Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4549\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004550Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004551
4552static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004553posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004554{
Victor Stinner8c62be82010-05-06 00:08:46 +00004555 pid_t pid;
4556 int result = 0;
4557 _PyImport_AcquireLock();
4558 pid = fork1();
4559 if (pid == 0) {
4560 /* child: this clobbers and resets the import lock. */
4561 PyOS_AfterFork();
4562 } else {
4563 /* parent: release the import lock. */
4564 result = _PyImport_ReleaseLock();
4565 }
4566 if (pid == -1)
4567 return posix_error();
4568 if (result < 0) {
4569 /* Don't clobber the OSError if the fork failed. */
4570 PyErr_SetString(PyExc_RuntimeError,
4571 "not holding the import lock");
4572 return NULL;
4573 }
4574 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004575}
4576#endif
4577
4578
Guido van Rossumad0ee831995-03-01 10:34:45 +00004579#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004580PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004581"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004582Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004583Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004584
Barry Warsaw53699e91996-12-10 23:23:01 +00004585static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004586posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004587{
Victor Stinner8c62be82010-05-06 00:08:46 +00004588 pid_t pid;
4589 int result = 0;
4590 _PyImport_AcquireLock();
4591 pid = fork();
4592 if (pid == 0) {
4593 /* child: this clobbers and resets the import lock. */
4594 PyOS_AfterFork();
4595 } else {
4596 /* parent: release the import lock. */
4597 result = _PyImport_ReleaseLock();
4598 }
4599 if (pid == -1)
4600 return posix_error();
4601 if (result < 0) {
4602 /* Don't clobber the OSError if the fork failed. */
4603 PyErr_SetString(PyExc_RuntimeError,
4604 "not holding the import lock");
4605 return NULL;
4606 }
4607 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004608}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004609#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004610
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004611#ifdef HAVE_SCHED_H
4612
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004613#ifdef HAVE_SCHED_GET_PRIORITY_MAX
4614
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004615PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
4616"sched_get_priority_max(policy)\n\n\
4617Get the maximum scheduling priority for *policy*.");
4618
4619static PyObject *
4620posix_sched_get_priority_max(PyObject *self, PyObject *args)
4621{
4622 int policy, max;
4623
4624 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
4625 return NULL;
4626 max = sched_get_priority_max(policy);
4627 if (max < 0)
4628 return posix_error();
4629 return PyLong_FromLong(max);
4630}
4631
4632PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
4633"sched_get_priority_min(policy)\n\n\
4634Get the minimum scheduling priority for *policy*.");
4635
4636static PyObject *
4637posix_sched_get_priority_min(PyObject *self, PyObject *args)
4638{
4639 int policy, min;
4640
4641 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
4642 return NULL;
4643 min = sched_get_priority_min(policy);
4644 if (min < 0)
4645 return posix_error();
4646 return PyLong_FromLong(min);
4647}
4648
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004649#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
4650
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004651#ifdef HAVE_SCHED_SETSCHEDULER
4652
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004653PyDoc_STRVAR(posix_sched_getscheduler__doc__,
4654"sched_getscheduler(pid)\n\n\
4655Get the scheduling policy for the process with a PID of *pid*.\n\
4656Passing a PID of 0 returns the scheduling policy for the calling process.");
4657
4658static PyObject *
4659posix_sched_getscheduler(PyObject *self, PyObject *args)
4660{
4661 pid_t pid;
4662 int policy;
4663
4664 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
4665 return NULL;
4666 policy = sched_getscheduler(pid);
4667 if (policy < 0)
4668 return posix_error();
4669 return PyLong_FromLong(policy);
4670}
4671
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004672#endif
4673
4674#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
4675
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004676static PyObject *
4677sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4678{
4679 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05004680 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004681
4682 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
4683 return NULL;
4684 res = PyStructSequence_New(type);
4685 if (!res)
4686 return NULL;
4687 Py_INCREF(priority);
4688 PyStructSequence_SET_ITEM(res, 0, priority);
4689 return res;
4690}
4691
4692PyDoc_STRVAR(sched_param__doc__,
4693"sched_param(sched_priority): A scheduling parameter.\n\n\
4694Current has only one field: sched_priority");
4695
4696static PyStructSequence_Field sched_param_fields[] = {
4697 {"sched_priority", "the scheduling priority"},
4698 {0}
4699};
4700
4701static PyStructSequence_Desc sched_param_desc = {
4702 "sched_param", /* name */
4703 sched_param__doc__, /* doc */
4704 sched_param_fields,
4705 1
4706};
4707
4708static int
4709convert_sched_param(PyObject *param, struct sched_param *res)
4710{
4711 long priority;
4712
4713 if (Py_TYPE(param) != &SchedParamType) {
4714 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
4715 return 0;
4716 }
4717 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
4718 if (priority == -1 && PyErr_Occurred())
4719 return 0;
4720 if (priority > INT_MAX || priority < INT_MIN) {
4721 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
4722 return 0;
4723 }
4724 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
4725 return 1;
4726}
4727
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004728#endif
4729
4730#ifdef HAVE_SCHED_SETSCHEDULER
4731
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004732PyDoc_STRVAR(posix_sched_setscheduler__doc__,
4733"sched_setscheduler(pid, policy, param)\n\n\
4734Set the scheduling policy, *policy*, for *pid*.\n\
4735If *pid* is 0, the calling process is changed.\n\
4736*param* is an instance of sched_param.");
4737
4738static PyObject *
4739posix_sched_setscheduler(PyObject *self, PyObject *args)
4740{
4741 pid_t pid;
4742 int policy;
4743 struct sched_param param;
4744
4745 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
4746 &pid, &policy, &convert_sched_param, &param))
4747 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02004748
4749 /*
Jesus Cea54b01492011-09-10 01:53:19 +02004750 ** sched_setscheduler() returns 0 in Linux, but the previous
4751 ** scheduling policy under Solaris/Illumos, and others.
4752 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02004753 */
4754 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004755 return posix_error();
4756 Py_RETURN_NONE;
4757}
4758
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004759#endif
4760
4761#ifdef HAVE_SCHED_SETPARAM
4762
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004763PyDoc_STRVAR(posix_sched_getparam__doc__,
4764"sched_getparam(pid) -> sched_param\n\n\
4765Returns scheduling parameters for the process with *pid* as an instance of the\n\
4766sched_param class. A PID of 0 means the calling process.");
4767
4768static PyObject *
4769posix_sched_getparam(PyObject *self, PyObject *args)
4770{
4771 pid_t pid;
4772 struct sched_param param;
4773 PyObject *res, *priority;
4774
4775 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
4776 return NULL;
4777 if (sched_getparam(pid, &param))
4778 return posix_error();
4779 res = PyStructSequence_New(&SchedParamType);
4780 if (!res)
4781 return NULL;
4782 priority = PyLong_FromLong(param.sched_priority);
4783 if (!priority) {
4784 Py_DECREF(res);
4785 return NULL;
4786 }
4787 PyStructSequence_SET_ITEM(res, 0, priority);
4788 return res;
4789}
4790
4791PyDoc_STRVAR(posix_sched_setparam__doc__,
4792"sched_setparam(pid, param)\n\n\
4793Set scheduling parameters for a process with PID *pid*.\n\
4794A PID of 0 means the calling process.");
4795
4796static PyObject *
4797posix_sched_setparam(PyObject *self, PyObject *args)
4798{
4799 pid_t pid;
4800 struct sched_param param;
4801
4802 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
4803 &pid, &convert_sched_param, &param))
4804 return NULL;
4805 if (sched_setparam(pid, &param))
4806 return posix_error();
4807 Py_RETURN_NONE;
4808}
4809
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004810#endif
4811
4812#ifdef HAVE_SCHED_RR_GET_INTERVAL
4813
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004814PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
4815"sched_rr_get_interval(pid) -> float\n\n\
4816Return the round-robin quantum for the process with PID *pid* in seconds.");
4817
4818static PyObject *
4819posix_sched_rr_get_interval(PyObject *self, PyObject *args)
4820{
4821 pid_t pid;
4822 struct timespec interval;
4823
4824 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
4825 return NULL;
4826 if (sched_rr_get_interval(pid, &interval))
4827 return posix_error();
4828 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
4829}
4830
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004831#endif
4832
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004833PyDoc_STRVAR(posix_sched_yield__doc__,
4834"sched_yield()\n\n\
4835Voluntarily relinquish the CPU.");
4836
4837static PyObject *
4838posix_sched_yield(PyObject *self, PyObject *noargs)
4839{
4840 if (sched_yield())
4841 return posix_error();
4842 Py_RETURN_NONE;
4843}
4844
Benjamin Peterson2740af82011-08-02 17:41:34 -05004845#ifdef HAVE_SCHED_SETAFFINITY
4846
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004847typedef struct {
4848 PyObject_HEAD;
4849 Py_ssize_t size;
4850 int ncpus;
4851 cpu_set_t *set;
4852} Py_cpu_set;
4853
4854static PyTypeObject cpu_set_type;
4855
4856static void
4857cpu_set_dealloc(Py_cpu_set *set)
4858{
4859 assert(set->set);
4860 CPU_FREE(set->set);
4861 Py_TYPE(set)->tp_free(set);
4862}
4863
4864static Py_cpu_set *
4865make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
4866{
4867 Py_cpu_set *set;
4868
4869 if (size < 0) {
4870 PyErr_SetString(PyExc_ValueError, "negative size");
4871 return NULL;
4872 }
4873 set = (Py_cpu_set *)type->tp_alloc(type, 0);
4874 if (!set)
4875 return NULL;
4876 set->ncpus = size;
4877 set->size = CPU_ALLOC_SIZE(size);
4878 set->set = CPU_ALLOC(size);
4879 if (!set->set) {
4880 type->tp_free(set);
4881 PyErr_NoMemory();
4882 return NULL;
4883 }
4884 CPU_ZERO_S(set->size, set->set);
4885 return set;
4886}
4887
4888static PyObject *
4889cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4890{
4891 int size;
4892
4893 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
4894 !PyArg_ParseTuple(args, "i:cpu_set", &size))
4895 return NULL;
4896 return (PyObject *)make_new_cpu_set(type, size);
4897}
4898
4899static PyObject *
4900cpu_set_repr(Py_cpu_set *set)
4901{
4902 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
4903}
4904
4905static Py_ssize_t
4906cpu_set_len(Py_cpu_set *set)
4907{
4908 return set->ncpus;
4909}
4910
4911static int
4912_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
4913{
4914 int cpu;
4915 if (!PyArg_ParseTuple(args, requester, &cpu))
4916 return -1;
4917 if (cpu < 0) {
4918 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
4919 return -1;
4920 }
4921 if (cpu >= set->ncpus) {
4922 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
4923 return -1;
4924 }
4925 return cpu;
4926}
4927
4928PyDoc_STRVAR(cpu_set_set_doc,
4929"cpu_set.set(i)\n\n\
4930Add CPU *i* to the set.");
4931
4932static PyObject *
4933cpu_set_set(Py_cpu_set *set, PyObject *args)
4934{
4935 int cpu = _get_cpu(set, "i|set", args);
4936 if (cpu == -1)
4937 return NULL;
4938 CPU_SET_S(cpu, set->size, set->set);
4939 Py_RETURN_NONE;
4940}
4941
4942PyDoc_STRVAR(cpu_set_count_doc,
4943"cpu_set.count() -> int\n\n\
4944Return the number of CPUs active in the set.");
4945
4946static PyObject *
4947cpu_set_count(Py_cpu_set *set, PyObject *noargs)
4948{
4949 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
4950}
4951
4952PyDoc_STRVAR(cpu_set_clear_doc,
4953"cpu_set.clear(i)\n\n\
4954Remove CPU *i* from the set.");
4955
4956static PyObject *
4957cpu_set_clear(Py_cpu_set *set, PyObject *args)
4958{
4959 int cpu = _get_cpu(set, "i|clear", args);
4960 if (cpu == -1)
4961 return NULL;
4962 CPU_CLR_S(cpu, set->size, set->set);
4963 Py_RETURN_NONE;
4964}
4965
4966PyDoc_STRVAR(cpu_set_isset_doc,
4967"cpu_set.isset(i) -> bool\n\n\
4968Test if CPU *i* is in the set.");
4969
4970static PyObject *
4971cpu_set_isset(Py_cpu_set *set, PyObject *args)
4972{
4973 int cpu = _get_cpu(set, "i|isset", args);
4974 if (cpu == -1)
4975 return NULL;
4976 if (CPU_ISSET_S(cpu, set->size, set->set))
4977 Py_RETURN_TRUE;
4978 Py_RETURN_FALSE;
4979}
4980
4981PyDoc_STRVAR(cpu_set_zero_doc,
4982"cpu_set.zero()\n\n\
4983Clear the cpu_set.");
4984
4985static PyObject *
4986cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
4987{
4988 CPU_ZERO_S(set->size, set->set);
4989 Py_RETURN_NONE;
4990}
4991
4992static PyObject *
4993cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
4994{
4995 int eq;
4996
Brian Curtindfc80e32011-08-10 20:28:54 -05004997 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
4998 Py_RETURN_NOTIMPLEMENTED;
4999
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005000 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5001 if ((op == Py_EQ) ? eq : !eq)
5002 Py_RETURN_TRUE;
5003 else
5004 Py_RETURN_FALSE;
5005}
5006
5007#define CPU_SET_BINOP(name, op) \
5008 static PyObject * \
5009 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5010 if (res) { \
5011 Py_INCREF(res); \
5012 } \
5013 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005014 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005015 if (!res) \
5016 return NULL; \
5017 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005018 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005019 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005020 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005021 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005022 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005023 op(res->size, res->set, left->set, right->set); \
5024 return (PyObject *)res; \
5025 } \
5026 static PyObject * \
5027 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5028 return do_cpu_set_##name(left, right, NULL); \
5029 } \
5030 static PyObject * \
5031 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5032 return do_cpu_set_##name(left, right, left); \
5033 } \
5034
5035CPU_SET_BINOP(and, CPU_AND_S)
5036CPU_SET_BINOP(or, CPU_OR_S)
5037CPU_SET_BINOP(xor, CPU_XOR_S)
5038#undef CPU_SET_BINOP
5039
5040PyDoc_STRVAR(cpu_set_doc,
5041"cpu_set(size)\n\n\
5042Create an empty mask of CPUs.");
5043
5044static PyNumberMethods cpu_set_as_number = {
5045 0, /*nb_add*/
5046 0, /*nb_subtract*/
5047 0, /*nb_multiply*/
5048 0, /*nb_remainder*/
5049 0, /*nb_divmod*/
5050 0, /*nb_power*/
5051 0, /*nb_negative*/
5052 0, /*nb_positive*/
5053 0, /*nb_absolute*/
5054 0, /*nb_bool*/
5055 0, /*nb_invert*/
5056 0, /*nb_lshift*/
5057 0, /*nb_rshift*/
5058 (binaryfunc)cpu_set_and, /*nb_and*/
5059 (binaryfunc)cpu_set_xor, /*nb_xor*/
5060 (binaryfunc)cpu_set_or, /*nb_or*/
5061 0, /*nb_int*/
5062 0, /*nb_reserved*/
5063 0, /*nb_float*/
5064 0, /*nb_inplace_add*/
5065 0, /*nb_inplace_subtract*/
5066 0, /*nb_inplace_multiply*/
5067 0, /*nb_inplace_remainder*/
5068 0, /*nb_inplace_power*/
5069 0, /*nb_inplace_lshift*/
5070 0, /*nb_inplace_rshift*/
5071 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5072 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5073 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5074};
5075
5076static PySequenceMethods cpu_set_as_sequence = {
5077 (lenfunc)cpu_set_len, /* sq_length */
5078};
5079
5080static PyMethodDef cpu_set_methods[] = {
5081 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5082 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5083 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5084 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5085 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5086 {NULL, NULL} /* sentinel */
5087};
5088
5089static PyTypeObject cpu_set_type = {
5090 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5091 "posix.cpu_set", /* tp_name */
5092 sizeof(Py_cpu_set), /* tp_basicsize */
5093 0, /* tp_itemsize */
5094 /* methods */
5095 (destructor)cpu_set_dealloc, /* tp_dealloc */
5096 0, /* tp_print */
5097 0, /* tp_getattr */
5098 0, /* tp_setattr */
5099 0, /* tp_reserved */
5100 (reprfunc)cpu_set_repr, /* tp_repr */
5101 &cpu_set_as_number, /* tp_as_number */
5102 &cpu_set_as_sequence, /* tp_as_sequence */
5103 0, /* tp_as_mapping */
5104 PyObject_HashNotImplemented, /* tp_hash */
5105 0, /* tp_call */
5106 0, /* tp_str */
5107 PyObject_GenericGetAttr, /* tp_getattro */
5108 0, /* tp_setattro */
5109 0, /* tp_as_buffer */
5110 Py_TPFLAGS_DEFAULT, /* tp_flags */
5111 cpu_set_doc, /* tp_doc */
5112 0, /* tp_traverse */
5113 0, /* tp_clear */
5114 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5115 0, /* tp_weaklistoffset */
5116 0, /* tp_iter */
5117 0, /* tp_iternext */
5118 cpu_set_methods, /* tp_methods */
5119 0, /* tp_members */
5120 0, /* tp_getset */
5121 0, /* tp_base */
5122 0, /* tp_dict */
5123 0, /* tp_descr_get */
5124 0, /* tp_descr_set */
5125 0, /* tp_dictoffset */
5126 0, /* tp_init */
5127 PyType_GenericAlloc, /* tp_alloc */
5128 cpu_set_new, /* tp_new */
5129 PyObject_Del, /* tp_free */
5130};
5131
5132PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5133"sched_setaffinity(pid, cpu_set)\n\n\
5134Set the affinity of the process with PID *pid* to *cpu_set*.");
5135
5136static PyObject *
5137posix_sched_setaffinity(PyObject *self, PyObject *args)
5138{
5139 pid_t pid;
5140 Py_cpu_set *cpu_set;
5141
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005142 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005143 &pid, &cpu_set_type, &cpu_set))
5144 return NULL;
5145 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5146 return posix_error();
5147 Py_RETURN_NONE;
5148}
5149
5150PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5151"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5152Return the affinity of the process with PID *pid*.\n\
5153The returned cpu_set will be of size *ncpus*.");
5154
5155static PyObject *
5156posix_sched_getaffinity(PyObject *self, PyObject *args)
5157{
5158 pid_t pid;
5159 int ncpus;
5160 Py_cpu_set *res;
5161
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005162 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005163 &pid, &ncpus))
5164 return NULL;
5165 res = make_new_cpu_set(&cpu_set_type, ncpus);
5166 if (!res)
5167 return NULL;
5168 if (sched_getaffinity(pid, res->size, res->set)) {
5169 Py_DECREF(res);
5170 return posix_error();
5171 }
5172 return (PyObject *)res;
5173}
5174
Benjamin Peterson2740af82011-08-02 17:41:34 -05005175#endif /* HAVE_SCHED_SETAFFINITY */
5176
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005177#endif /* HAVE_SCHED_H */
5178
Neal Norwitzb59798b2003-03-21 01:43:31 +00005179/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005180/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5181#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005182#define DEV_PTY_FILE "/dev/ptc"
5183#define HAVE_DEV_PTMX
5184#else
5185#define DEV_PTY_FILE "/dev/ptmx"
5186#endif
5187
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005188#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005189#ifdef HAVE_PTY_H
5190#include <pty.h>
5191#else
5192#ifdef HAVE_LIBUTIL_H
5193#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005194#else
5195#ifdef HAVE_UTIL_H
5196#include <util.h>
5197#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005198#endif /* HAVE_LIBUTIL_H */
5199#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005200#ifdef HAVE_STROPTS_H
5201#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005202#endif
5203#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005204
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005205#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005206PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005207"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005208Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005209
5210static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005211posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005212{
Victor Stinner8c62be82010-05-06 00:08:46 +00005213 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005214#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005215 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005216#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005217#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005218 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005219#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005220 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005221#endif
5222#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005223
Thomas Wouters70c21a12000-07-14 14:28:33 +00005224#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5226 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005227#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5229 if (slave_name == NULL)
5230 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005231
Victor Stinner8c62be82010-05-06 00:08:46 +00005232 slave_fd = open(slave_name, O_RDWR);
5233 if (slave_fd < 0)
5234 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005235#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005236 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5237 if (master_fd < 0)
5238 return posix_error();
5239 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5240 /* change permission of slave */
5241 if (grantpt(master_fd) < 0) {
5242 PyOS_setsig(SIGCHLD, sig_saved);
5243 return posix_error();
5244 }
5245 /* unlock slave */
5246 if (unlockpt(master_fd) < 0) {
5247 PyOS_setsig(SIGCHLD, sig_saved);
5248 return posix_error();
5249 }
5250 PyOS_setsig(SIGCHLD, sig_saved);
5251 slave_name = ptsname(master_fd); /* get name of slave */
5252 if (slave_name == NULL)
5253 return posix_error();
5254 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5255 if (slave_fd < 0)
5256 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005257#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005258 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5259 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005260#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005261 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005262#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005263#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005264#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005265
Victor Stinner8c62be82010-05-06 00:08:46 +00005266 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005267
Fred Drake8cef4cf2000-06-28 16:40:38 +00005268}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005269#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005270
5271#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005272PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005273"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005274Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5275Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005276To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005277
5278static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005279posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005280{
Victor Stinner8c62be82010-05-06 00:08:46 +00005281 int master_fd = -1, result = 0;
5282 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005283
Victor Stinner8c62be82010-05-06 00:08:46 +00005284 _PyImport_AcquireLock();
5285 pid = forkpty(&master_fd, NULL, NULL, NULL);
5286 if (pid == 0) {
5287 /* child: this clobbers and resets the import lock. */
5288 PyOS_AfterFork();
5289 } else {
5290 /* parent: release the import lock. */
5291 result = _PyImport_ReleaseLock();
5292 }
5293 if (pid == -1)
5294 return posix_error();
5295 if (result < 0) {
5296 /* Don't clobber the OSError if the fork failed. */
5297 PyErr_SetString(PyExc_RuntimeError,
5298 "not holding the import lock");
5299 return NULL;
5300 }
5301 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005302}
5303#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005304
Ross Lagerwall7807c352011-03-17 20:20:30 +02005305
Guido van Rossumad0ee831995-03-01 10:34:45 +00005306#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005307PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005308"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005309Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005310
Barry Warsaw53699e91996-12-10 23:23:01 +00005311static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005312posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005313{
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005315}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005316#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005317
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005318
Guido van Rossumad0ee831995-03-01 10:34:45 +00005319#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005320PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005321"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005322Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005323
Barry Warsaw53699e91996-12-10 23:23:01 +00005324static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005325posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005326{
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005328}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005329#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005330
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005331
Guido van Rossumad0ee831995-03-01 10:34:45 +00005332#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005333PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005334"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005335Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005336
Barry Warsaw53699e91996-12-10 23:23:01 +00005337static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005338posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005339{
Victor Stinner8c62be82010-05-06 00:08:46 +00005340 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005341}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005342#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005345PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005346"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005347Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005348
Barry Warsaw53699e91996-12-10 23:23:01 +00005349static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005350posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005351{
Victor Stinner8c62be82010-05-06 00:08:46 +00005352 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005353}
5354
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005355#ifdef HAVE_GETGROUPLIST
5356PyDoc_STRVAR(posix_getgrouplist__doc__,
5357"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5358Returns a list of groups to which a user belongs.\n\n\
5359 user: username to lookup\n\
5360 group: base group id of the user");
5361
5362static PyObject *
5363posix_getgrouplist(PyObject *self, PyObject *args)
5364{
5365#ifdef NGROUPS_MAX
5366#define MAX_GROUPS NGROUPS_MAX
5367#else
5368 /* defined to be 16 on Solaris7, so this should be a small number */
5369#define MAX_GROUPS 64
5370#endif
5371
5372 const char *user;
5373 int i, ngroups;
5374 PyObject *list;
5375#ifdef __APPLE__
5376 int *groups, basegid;
5377#else
5378 gid_t *groups, basegid;
5379#endif
5380 ngroups = MAX_GROUPS;
5381
5382 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5383 return NULL;
5384
5385#ifdef __APPLE__
5386 groups = PyMem_Malloc(ngroups * sizeof(int));
5387#else
5388 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5389#endif
5390 if (groups == NULL)
5391 return PyErr_NoMemory();
5392
5393 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5394 PyMem_Del(groups);
5395 return posix_error();
5396 }
5397
5398 list = PyList_New(ngroups);
5399 if (list == NULL) {
5400 PyMem_Del(groups);
5401 return NULL;
5402 }
5403
5404 for (i = 0; i < ngroups; i++) {
5405 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5406 if (o == NULL) {
5407 Py_DECREF(list);
5408 PyMem_Del(groups);
5409 return NULL;
5410 }
5411 PyList_SET_ITEM(list, i, o);
5412 }
5413
5414 PyMem_Del(groups);
5415
5416 return list;
5417}
5418#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005419
Fred Drakec9680921999-12-13 16:37:25 +00005420#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005421PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005422"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005423Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005424
5425static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005426posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005427{
5428 PyObject *result = NULL;
5429
Fred Drakec9680921999-12-13 16:37:25 +00005430#ifdef NGROUPS_MAX
5431#define MAX_GROUPS NGROUPS_MAX
5432#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005433 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005434#define MAX_GROUPS 64
5435#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005436 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005437
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005438 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005439 * This is a helper variable to store the intermediate result when
5440 * that happens.
5441 *
5442 * To keep the code readable the OSX behaviour is unconditional,
5443 * according to the POSIX spec this should be safe on all unix-y
5444 * systems.
5445 */
5446 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005447 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005448
Victor Stinner8c62be82010-05-06 00:08:46 +00005449 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005450 if (n < 0) {
5451 if (errno == EINVAL) {
5452 n = getgroups(0, NULL);
5453 if (n == -1) {
5454 return posix_error();
5455 }
5456 if (n == 0) {
5457 /* Avoid malloc(0) */
5458 alt_grouplist = grouplist;
5459 } else {
5460 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5461 if (alt_grouplist == NULL) {
5462 errno = EINVAL;
5463 return posix_error();
5464 }
5465 n = getgroups(n, alt_grouplist);
5466 if (n == -1) {
5467 PyMem_Free(alt_grouplist);
5468 return posix_error();
5469 }
5470 }
5471 } else {
5472 return posix_error();
5473 }
5474 }
5475 result = PyList_New(n);
5476 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005477 int i;
5478 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005479 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005480 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005481 Py_DECREF(result);
5482 result = NULL;
5483 break;
Fred Drakec9680921999-12-13 16:37:25 +00005484 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005485 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005486 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005487 }
5488
5489 if (alt_grouplist != grouplist) {
5490 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005491 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005492
Fred Drakec9680921999-12-13 16:37:25 +00005493 return result;
5494}
5495#endif
5496
Antoine Pitroub7572f02009-12-02 20:46:48 +00005497#ifdef HAVE_INITGROUPS
5498PyDoc_STRVAR(posix_initgroups__doc__,
5499"initgroups(username, gid) -> None\n\n\
5500Call the system initgroups() to initialize the group access list with all of\n\
5501the groups of which the specified username is a member, plus the specified\n\
5502group id.");
5503
5504static PyObject *
5505posix_initgroups(PyObject *self, PyObject *args)
5506{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005507 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005508 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005509 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005510 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005511
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005512 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5513 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005514 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005515 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005516
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005517 res = initgroups(username, (gid_t) gid);
5518 Py_DECREF(oname);
5519 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005520 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005521
Victor Stinner8c62be82010-05-06 00:08:46 +00005522 Py_INCREF(Py_None);
5523 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005524}
5525#endif
5526
Martin v. Löwis606edc12002-06-13 21:09:11 +00005527#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005528PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005529"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005530Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005531
5532static PyObject *
5533posix_getpgid(PyObject *self, PyObject *args)
5534{
Victor Stinner8c62be82010-05-06 00:08:46 +00005535 pid_t pid, pgid;
5536 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5537 return NULL;
5538 pgid = getpgid(pid);
5539 if (pgid < 0)
5540 return posix_error();
5541 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005542}
5543#endif /* HAVE_GETPGID */
5544
5545
Guido van Rossumb6775db1994-08-01 11:34:53 +00005546#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005547PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005548"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005549Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005550
Barry Warsaw53699e91996-12-10 23:23:01 +00005551static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005552posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005553{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005554#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005555 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005556#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005557 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005558#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005559}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005560#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005561
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005562
Guido van Rossumb6775db1994-08-01 11:34:53 +00005563#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005564PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005565"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005566Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005567
Barry Warsaw53699e91996-12-10 23:23:01 +00005568static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005569posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005570{
Guido van Rossum64933891994-10-20 21:56:42 +00005571#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005572 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005573#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005575#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005576 return posix_error();
5577 Py_INCREF(Py_None);
5578 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005579}
5580
Guido van Rossumb6775db1994-08-01 11:34:53 +00005581#endif /* HAVE_SETPGRP */
5582
Guido van Rossumad0ee831995-03-01 10:34:45 +00005583#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005584
5585#ifdef MS_WINDOWS
5586#include <tlhelp32.h>
5587
5588static PyObject*
5589win32_getppid()
5590{
5591 HANDLE snapshot;
5592 pid_t mypid;
5593 PyObject* result = NULL;
5594 BOOL have_record;
5595 PROCESSENTRY32 pe;
5596
5597 mypid = getpid(); /* This function never fails */
5598
5599 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5600 if (snapshot == INVALID_HANDLE_VALUE)
5601 return PyErr_SetFromWindowsErr(GetLastError());
5602
5603 pe.dwSize = sizeof(pe);
5604 have_record = Process32First(snapshot, &pe);
5605 while (have_record) {
5606 if (mypid == (pid_t)pe.th32ProcessID) {
5607 /* We could cache the ulong value in a static variable. */
5608 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5609 break;
5610 }
5611
5612 have_record = Process32Next(snapshot, &pe);
5613 }
5614
5615 /* If our loop exits and our pid was not found (result will be NULL)
5616 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5617 * error anyway, so let's raise it. */
5618 if (!result)
5619 result = PyErr_SetFromWindowsErr(GetLastError());
5620
5621 CloseHandle(snapshot);
5622
5623 return result;
5624}
5625#endif /*MS_WINDOWS*/
5626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005627PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005628"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005629Return the parent's process id. If the parent process has already exited,\n\
5630Windows machines will still return its id; others systems will return the id\n\
5631of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005632
Barry Warsaw53699e91996-12-10 23:23:01 +00005633static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005634posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005635{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005636#ifdef MS_WINDOWS
5637 return win32_getppid();
5638#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005639 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005640#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005641}
5642#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005643
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005644
Fred Drake12c6e2d1999-12-14 21:25:03 +00005645#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005646PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005647"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005648Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005649
5650static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005651posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005652{
Victor Stinner8c62be82010-05-06 00:08:46 +00005653 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005654#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005655 wchar_t user_name[UNLEN + 1];
5656 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
5657
5658 if (GetUserNameW(user_name, &num_chars)) {
5659 /* num_chars is the number of unicode chars plus null terminator */
5660 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005661 }
5662 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005663 result = PyErr_SetFromWindowsErr(GetLastError());
5664#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005665 char *name;
5666 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005667
Victor Stinner8c62be82010-05-06 00:08:46 +00005668 errno = 0;
5669 name = getlogin();
5670 if (name == NULL) {
5671 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005672 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005673 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005674 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005675 }
5676 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005677 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005678 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005679#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005680 return result;
5681}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005682#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005683
Guido van Rossumad0ee831995-03-01 10:34:45 +00005684#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005685PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005686"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005687Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005688
Barry Warsaw53699e91996-12-10 23:23:01 +00005689static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005690posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005691{
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005693}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005694#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005696
Guido van Rossumad0ee831995-03-01 10:34:45 +00005697#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005698PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005699"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005700Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005701
Barry Warsaw53699e91996-12-10 23:23:01 +00005702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005703posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005704{
Victor Stinner8c62be82010-05-06 00:08:46 +00005705 pid_t pid;
5706 int sig;
5707 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5708 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005709#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005710 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
5711 APIRET rc;
5712 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005713 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005714
5715 } else if (sig == XCPT_SIGNAL_KILLPROC) {
5716 APIRET rc;
5717 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005718 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005719
5720 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005721 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005722#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005723 if (kill(pid, sig) == -1)
5724 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005725#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005726 Py_INCREF(Py_None);
5727 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005728}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005729#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005730
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005731#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005732PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005733"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005734Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005735
5736static PyObject *
5737posix_killpg(PyObject *self, PyObject *args)
5738{
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 int sig;
5740 pid_t pgid;
5741 /* XXX some man pages make the `pgid` parameter an int, others
5742 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5743 take the same type. Moreover, pid_t is always at least as wide as
5744 int (else compilation of this module fails), which is safe. */
5745 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5746 return NULL;
5747 if (killpg(pgid, sig) == -1)
5748 return posix_error();
5749 Py_INCREF(Py_None);
5750 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005751}
5752#endif
5753
Brian Curtineb24d742010-04-12 17:16:38 +00005754#ifdef MS_WINDOWS
5755PyDoc_STRVAR(win32_kill__doc__,
5756"kill(pid, sig)\n\n\
5757Kill a process with a signal.");
5758
5759static PyObject *
5760win32_kill(PyObject *self, PyObject *args)
5761{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005762 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005763 DWORD pid, sig, err;
5764 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005765
Victor Stinner8c62be82010-05-06 00:08:46 +00005766 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5767 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005768
Victor Stinner8c62be82010-05-06 00:08:46 +00005769 /* Console processes which share a common console can be sent CTRL+C or
5770 CTRL+BREAK events, provided they handle said events. */
5771 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
5772 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
5773 err = GetLastError();
5774 PyErr_SetFromWindowsErr(err);
5775 }
5776 else
5777 Py_RETURN_NONE;
5778 }
Brian Curtineb24d742010-04-12 17:16:38 +00005779
Victor Stinner8c62be82010-05-06 00:08:46 +00005780 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
5781 attempt to open and terminate the process. */
5782 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
5783 if (handle == NULL) {
5784 err = GetLastError();
5785 return PyErr_SetFromWindowsErr(err);
5786 }
Brian Curtineb24d742010-04-12 17:16:38 +00005787
Victor Stinner8c62be82010-05-06 00:08:46 +00005788 if (TerminateProcess(handle, sig) == 0) {
5789 err = GetLastError();
5790 result = PyErr_SetFromWindowsErr(err);
5791 } else {
5792 Py_INCREF(Py_None);
5793 result = Py_None;
5794 }
Brian Curtineb24d742010-04-12 17:16:38 +00005795
Victor Stinner8c62be82010-05-06 00:08:46 +00005796 CloseHandle(handle);
5797 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00005798}
5799#endif /* MS_WINDOWS */
5800
Guido van Rossumc0125471996-06-28 18:55:32 +00005801#ifdef HAVE_PLOCK
5802
5803#ifdef HAVE_SYS_LOCK_H
5804#include <sys/lock.h>
5805#endif
5806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005807PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005808"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005809Lock program segments into memory.");
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_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00005813{
Victor Stinner8c62be82010-05-06 00:08:46 +00005814 int op;
5815 if (!PyArg_ParseTuple(args, "i:plock", &op))
5816 return NULL;
5817 if (plock(op) == -1)
5818 return posix_error();
5819 Py_INCREF(Py_None);
5820 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00005821}
5822#endif
5823
Guido van Rossumb6775db1994-08-01 11:34:53 +00005824#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005825PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005826"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005827Set the current process's user id.");
5828
Barry Warsaw53699e91996-12-10 23:23:01 +00005829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005830posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005831{
Victor Stinner8c62be82010-05-06 00:08:46 +00005832 long uid_arg;
5833 uid_t uid;
5834 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5835 return NULL;
5836 uid = uid_arg;
5837 if (uid != uid_arg) {
5838 PyErr_SetString(PyExc_OverflowError, "user id too big");
5839 return NULL;
5840 }
5841 if (setuid(uid) < 0)
5842 return posix_error();
5843 Py_INCREF(Py_None);
5844 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005845}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005846#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005848
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005849#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005850PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005851"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005852Set the current process's effective user id.");
5853
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005854static PyObject *
5855posix_seteuid (PyObject *self, PyObject *args)
5856{
Victor Stinner8c62be82010-05-06 00:08:46 +00005857 long euid_arg;
5858 uid_t euid;
5859 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5860 return NULL;
5861 euid = euid_arg;
5862 if (euid != euid_arg) {
5863 PyErr_SetString(PyExc_OverflowError, "user id too big");
5864 return NULL;
5865 }
5866 if (seteuid(euid) < 0) {
5867 return posix_error();
5868 } else {
5869 Py_INCREF(Py_None);
5870 return Py_None;
5871 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005872}
5873#endif /* HAVE_SETEUID */
5874
5875#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005876PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005877"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005878Set the current process's effective group id.");
5879
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005880static PyObject *
5881posix_setegid (PyObject *self, PyObject *args)
5882{
Victor Stinner8c62be82010-05-06 00:08:46 +00005883 long egid_arg;
5884 gid_t egid;
5885 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5886 return NULL;
5887 egid = egid_arg;
5888 if (egid != egid_arg) {
5889 PyErr_SetString(PyExc_OverflowError, "group id too big");
5890 return NULL;
5891 }
5892 if (setegid(egid) < 0) {
5893 return posix_error();
5894 } else {
5895 Py_INCREF(Py_None);
5896 return Py_None;
5897 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005898}
5899#endif /* HAVE_SETEGID */
5900
5901#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005902PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005903"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005904Set the current process's real and effective user ids.");
5905
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005906static PyObject *
5907posix_setreuid (PyObject *self, PyObject *args)
5908{
Victor Stinner8c62be82010-05-06 00:08:46 +00005909 long ruid_arg, euid_arg;
5910 uid_t ruid, euid;
5911 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5912 return NULL;
5913 if (ruid_arg == -1)
5914 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5915 else
5916 ruid = ruid_arg; /* otherwise, assign from our long */
5917 if (euid_arg == -1)
5918 euid = (uid_t)-1;
5919 else
5920 euid = euid_arg;
5921 if ((euid_arg != -1 && euid != euid_arg) ||
5922 (ruid_arg != -1 && ruid != ruid_arg)) {
5923 PyErr_SetString(PyExc_OverflowError, "user id too big");
5924 return NULL;
5925 }
5926 if (setreuid(ruid, euid) < 0) {
5927 return posix_error();
5928 } else {
5929 Py_INCREF(Py_None);
5930 return Py_None;
5931 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005932}
5933#endif /* HAVE_SETREUID */
5934
5935#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005936PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005937"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005938Set the current process's real and effective group ids.");
5939
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005940static PyObject *
5941posix_setregid (PyObject *self, PyObject *args)
5942{
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 long rgid_arg, egid_arg;
5944 gid_t rgid, egid;
5945 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5946 return NULL;
5947 if (rgid_arg == -1)
5948 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
5949 else
5950 rgid = rgid_arg; /* otherwise, assign from our long */
5951 if (egid_arg == -1)
5952 egid = (gid_t)-1;
5953 else
5954 egid = egid_arg;
5955 if ((egid_arg != -1 && egid != egid_arg) ||
5956 (rgid_arg != -1 && rgid != rgid_arg)) {
5957 PyErr_SetString(PyExc_OverflowError, "group id too big");
5958 return NULL;
5959 }
5960 if (setregid(rgid, egid) < 0) {
5961 return posix_error();
5962 } else {
5963 Py_INCREF(Py_None);
5964 return Py_None;
5965 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005966}
5967#endif /* HAVE_SETREGID */
5968
Guido van Rossumb6775db1994-08-01 11:34:53 +00005969#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005970PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005971"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005972Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005973
Barry Warsaw53699e91996-12-10 23:23:01 +00005974static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005975posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005976{
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 long gid_arg;
5978 gid_t gid;
5979 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
5980 return NULL;
5981 gid = gid_arg;
5982 if (gid != gid_arg) {
5983 PyErr_SetString(PyExc_OverflowError, "group id too big");
5984 return NULL;
5985 }
5986 if (setgid(gid) < 0)
5987 return posix_error();
5988 Py_INCREF(Py_None);
5989 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005990}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005991#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005992
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005993#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005994PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005995"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005996Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005997
5998static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00005999posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006000{
Victor Stinner8c62be82010-05-06 00:08:46 +00006001 int i, len;
6002 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006003
Victor Stinner8c62be82010-05-06 00:08:46 +00006004 if (!PySequence_Check(groups)) {
6005 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6006 return NULL;
6007 }
6008 len = PySequence_Size(groups);
6009 if (len > MAX_GROUPS) {
6010 PyErr_SetString(PyExc_ValueError, "too many groups");
6011 return NULL;
6012 }
6013 for(i = 0; i < len; i++) {
6014 PyObject *elem;
6015 elem = PySequence_GetItem(groups, i);
6016 if (!elem)
6017 return NULL;
6018 if (!PyLong_Check(elem)) {
6019 PyErr_SetString(PyExc_TypeError,
6020 "groups must be integers");
6021 Py_DECREF(elem);
6022 return NULL;
6023 } else {
6024 unsigned long x = PyLong_AsUnsignedLong(elem);
6025 if (PyErr_Occurred()) {
6026 PyErr_SetString(PyExc_TypeError,
6027 "group id too big");
6028 Py_DECREF(elem);
6029 return NULL;
6030 }
6031 grouplist[i] = x;
6032 /* read back the value to see if it fitted in gid_t */
6033 if (grouplist[i] != x) {
6034 PyErr_SetString(PyExc_TypeError,
6035 "group id too big");
6036 Py_DECREF(elem);
6037 return NULL;
6038 }
6039 }
6040 Py_DECREF(elem);
6041 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006042
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 if (setgroups(len, grouplist) < 0)
6044 return posix_error();
6045 Py_INCREF(Py_None);
6046 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006047}
6048#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006049
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006050#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6051static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00006052wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006053{
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 PyObject *result;
6055 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006056
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 if (pid == -1)
6058 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006059
Victor Stinner8c62be82010-05-06 00:08:46 +00006060 if (struct_rusage == NULL) {
6061 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6062 if (m == NULL)
6063 return NULL;
6064 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
6065 Py_DECREF(m);
6066 if (struct_rusage == NULL)
6067 return NULL;
6068 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006069
Victor Stinner8c62be82010-05-06 00:08:46 +00006070 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6071 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6072 if (!result)
6073 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006074
6075#ifndef doubletime
6076#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6077#endif
6078
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 PyStructSequence_SET_ITEM(result, 0,
6080 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6081 PyStructSequence_SET_ITEM(result, 1,
6082 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006083#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006084 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6085 SET_INT(result, 2, ru->ru_maxrss);
6086 SET_INT(result, 3, ru->ru_ixrss);
6087 SET_INT(result, 4, ru->ru_idrss);
6088 SET_INT(result, 5, ru->ru_isrss);
6089 SET_INT(result, 6, ru->ru_minflt);
6090 SET_INT(result, 7, ru->ru_majflt);
6091 SET_INT(result, 8, ru->ru_nswap);
6092 SET_INT(result, 9, ru->ru_inblock);
6093 SET_INT(result, 10, ru->ru_oublock);
6094 SET_INT(result, 11, ru->ru_msgsnd);
6095 SET_INT(result, 12, ru->ru_msgrcv);
6096 SET_INT(result, 13, ru->ru_nsignals);
6097 SET_INT(result, 14, ru->ru_nvcsw);
6098 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006099#undef SET_INT
6100
Victor Stinner8c62be82010-05-06 00:08:46 +00006101 if (PyErr_Occurred()) {
6102 Py_DECREF(result);
6103 return NULL;
6104 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006105
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006107}
6108#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6109
6110#ifdef HAVE_WAIT3
6111PyDoc_STRVAR(posix_wait3__doc__,
6112"wait3(options) -> (pid, status, rusage)\n\n\
6113Wait for completion of a child process.");
6114
6115static PyObject *
6116posix_wait3(PyObject *self, PyObject *args)
6117{
Victor Stinner8c62be82010-05-06 00:08:46 +00006118 pid_t pid;
6119 int options;
6120 struct rusage ru;
6121 WAIT_TYPE status;
6122 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006123
Victor Stinner8c62be82010-05-06 00:08:46 +00006124 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6125 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006126
Victor Stinner8c62be82010-05-06 00:08:46 +00006127 Py_BEGIN_ALLOW_THREADS
6128 pid = wait3(&status, options, &ru);
6129 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006130
Victor Stinner8c62be82010-05-06 00:08:46 +00006131 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006132}
6133#endif /* HAVE_WAIT3 */
6134
6135#ifdef HAVE_WAIT4
6136PyDoc_STRVAR(posix_wait4__doc__,
6137"wait4(pid, options) -> (pid, status, rusage)\n\n\
6138Wait for completion of a given child process.");
6139
6140static PyObject *
6141posix_wait4(PyObject *self, PyObject *args)
6142{
Victor Stinner8c62be82010-05-06 00:08:46 +00006143 pid_t pid;
6144 int options;
6145 struct rusage ru;
6146 WAIT_TYPE status;
6147 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006148
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
6150 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006151
Victor Stinner8c62be82010-05-06 00:08:46 +00006152 Py_BEGIN_ALLOW_THREADS
6153 pid = wait4(pid, &status, options, &ru);
6154 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006155
Victor Stinner8c62be82010-05-06 00:08:46 +00006156 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006157}
6158#endif /* HAVE_WAIT4 */
6159
Ross Lagerwall7807c352011-03-17 20:20:30 +02006160#if defined(HAVE_WAITID) && !defined(__APPLE__)
6161PyDoc_STRVAR(posix_waitid__doc__,
6162"waitid(idtype, id, options) -> waitid_result\n\n\
6163Wait for the completion of one or more child processes.\n\n\
6164idtype can be P_PID, P_PGID or P_ALL.\n\
6165id specifies the pid to wait on.\n\
6166options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6167or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6168Returns either waitid_result or None if WNOHANG is specified and there are\n\
6169no children in a waitable state.");
6170
6171static PyObject *
6172posix_waitid(PyObject *self, PyObject *args)
6173{
6174 PyObject *result;
6175 idtype_t idtype;
6176 id_t id;
6177 int options, res;
6178 siginfo_t si;
6179 si.si_pid = 0;
6180 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6181 return NULL;
6182 Py_BEGIN_ALLOW_THREADS
6183 res = waitid(idtype, id, &si, options);
6184 Py_END_ALLOW_THREADS
6185 if (res == -1)
6186 return posix_error();
6187
6188 if (si.si_pid == 0)
6189 Py_RETURN_NONE;
6190
6191 result = PyStructSequence_New(&WaitidResultType);
6192 if (!result)
6193 return NULL;
6194
6195 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6196 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6197 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6198 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6199 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6200 if (PyErr_Occurred()) {
6201 Py_DECREF(result);
6202 return NULL;
6203 }
6204
6205 return result;
6206}
6207#endif
6208
Guido van Rossumb6775db1994-08-01 11:34:53 +00006209#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006210PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006211"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006212Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006213
Barry Warsaw53699e91996-12-10 23:23:01 +00006214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006215posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006216{
Victor Stinner8c62be82010-05-06 00:08:46 +00006217 pid_t pid;
6218 int options;
6219 WAIT_TYPE status;
6220 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006221
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6223 return NULL;
6224 Py_BEGIN_ALLOW_THREADS
6225 pid = waitpid(pid, &status, options);
6226 Py_END_ALLOW_THREADS
6227 if (pid == -1)
6228 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006229
Victor Stinner8c62be82010-05-06 00:08:46 +00006230 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006231}
6232
Tim Petersab034fa2002-02-01 11:27:43 +00006233#elif defined(HAVE_CWAIT)
6234
6235/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006236PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006237"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006238"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006239
6240static PyObject *
6241posix_waitpid(PyObject *self, PyObject *args)
6242{
Victor Stinner8c62be82010-05-06 00:08:46 +00006243 Py_intptr_t pid;
6244 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006245
Victor Stinner8c62be82010-05-06 00:08:46 +00006246 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6247 return NULL;
6248 Py_BEGIN_ALLOW_THREADS
6249 pid = _cwait(&status, pid, options);
6250 Py_END_ALLOW_THREADS
6251 if (pid == -1)
6252 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006253
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 /* shift the status left a byte so this is more like the POSIX waitpid */
6255 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006256}
6257#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006258
Guido van Rossumad0ee831995-03-01 10:34:45 +00006259#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006260PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006261"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006262Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006263
Barry Warsaw53699e91996-12-10 23:23:01 +00006264static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006265posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006266{
Victor Stinner8c62be82010-05-06 00:08:46 +00006267 pid_t pid;
6268 WAIT_TYPE status;
6269 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006270
Victor Stinner8c62be82010-05-06 00:08:46 +00006271 Py_BEGIN_ALLOW_THREADS
6272 pid = wait(&status);
6273 Py_END_ALLOW_THREADS
6274 if (pid == -1)
6275 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006276
Victor Stinner8c62be82010-05-06 00:08:46 +00006277 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006278}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006279#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006281
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006282PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006283"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006284Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006285
Barry Warsaw53699e91996-12-10 23:23:01 +00006286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006287posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006288{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006289#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006291#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006292#ifdef MS_WINDOWS
Brian Curtind25aef52011-06-13 15:16:04 -05006293 return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00006294 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006295#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006297#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006298#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006299}
6300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006301
Guido van Rossumb6775db1994-08-01 11:34:53 +00006302#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006303PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006304"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006305Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006306
Barry Warsaw53699e91996-12-10 23:23:01 +00006307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006308posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006309{
Victor Stinner8c62be82010-05-06 00:08:46 +00006310 PyObject* v;
6311 char buf[MAXPATHLEN];
6312 PyObject *opath;
6313 char *path;
6314 int n;
6315 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006316
Victor Stinner8c62be82010-05-06 00:08:46 +00006317 if (!PyArg_ParseTuple(args, "O&:readlink",
6318 PyUnicode_FSConverter, &opath))
6319 return NULL;
6320 path = PyBytes_AsString(opath);
6321 v = PySequence_GetItem(args, 0);
6322 if (v == NULL) {
6323 Py_DECREF(opath);
6324 return NULL;
6325 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00006326
Victor Stinner8c62be82010-05-06 00:08:46 +00006327 if (PyUnicode_Check(v)) {
6328 arg_is_unicode = 1;
6329 }
6330 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006331
Victor Stinner8c62be82010-05-06 00:08:46 +00006332 Py_BEGIN_ALLOW_THREADS
6333 n = readlink(path, buf, (int) sizeof buf);
6334 Py_END_ALLOW_THREADS
6335 if (n < 0)
6336 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006337
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00006339 if (arg_is_unicode)
6340 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
6341 else
6342 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006343}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006344#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006346
Brian Curtin52173d42010-12-02 18:29:18 +00006347#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006348PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006349"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006350Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006351
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006353posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006354{
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006356}
6357#endif /* HAVE_SYMLINK */
6358
Brian Curtind40e6f72010-07-08 21:39:08 +00006359#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6360
6361PyDoc_STRVAR(win_readlink__doc__,
6362"readlink(path) -> path\n\n\
6363Return a string representing the path to which the symbolic link points.");
6364
Brian Curtind40e6f72010-07-08 21:39:08 +00006365/* Windows readlink implementation */
6366static PyObject *
6367win_readlink(PyObject *self, PyObject *args)
6368{
6369 wchar_t *path;
6370 DWORD n_bytes_returned;
6371 DWORD io_result;
6372 PyObject *result;
6373 HANDLE reparse_point_handle;
6374
6375 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6376 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6377 wchar_t *print_name;
6378
6379 if (!PyArg_ParseTuple(args,
6380 "u:readlink",
6381 &path))
6382 return NULL;
6383
6384 /* First get a handle to the reparse point */
6385 Py_BEGIN_ALLOW_THREADS
6386 reparse_point_handle = CreateFileW(
6387 path,
6388 0,
6389 0,
6390 0,
6391 OPEN_EXISTING,
6392 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6393 0);
6394 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006395
Brian Curtind40e6f72010-07-08 21:39:08 +00006396 if (reparse_point_handle==INVALID_HANDLE_VALUE)
6397 {
6398 return win32_error_unicode("readlink", path);
6399 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006400
Brian Curtind40e6f72010-07-08 21:39:08 +00006401 Py_BEGIN_ALLOW_THREADS
6402 /* New call DeviceIoControl to read the reparse point */
6403 io_result = DeviceIoControl(
6404 reparse_point_handle,
6405 FSCTL_GET_REPARSE_POINT,
6406 0, 0, /* in buffer */
6407 target_buffer, sizeof(target_buffer),
6408 &n_bytes_returned,
6409 0 /* we're not using OVERLAPPED_IO */
6410 );
6411 CloseHandle(reparse_point_handle);
6412 Py_END_ALLOW_THREADS
6413
6414 if (io_result==0)
6415 {
6416 return win32_error_unicode("readlink", path);
6417 }
6418
6419 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6420 {
6421 PyErr_SetString(PyExc_ValueError,
6422 "not a symbolic link");
6423 return NULL;
6424 }
Brian Curtin74e45612010-07-09 15:58:59 +00006425 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6426 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6427
6428 result = PyUnicode_FromWideChar(print_name,
6429 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006430 return result;
6431}
6432
6433#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6434
Brian Curtin52173d42010-12-02 18:29:18 +00006435#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00006436
6437/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6438static int has_CreateSymbolicLinkW = 0;
6439static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
6440static int
6441check_CreateSymbolicLinkW()
6442{
6443 HINSTANCE hKernel32;
6444 /* only recheck */
6445 if (has_CreateSymbolicLinkW)
6446 return has_CreateSymbolicLinkW;
6447 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00006448 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6449 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00006450 if (Py_CreateSymbolicLinkW)
6451 has_CreateSymbolicLinkW = 1;
6452 return has_CreateSymbolicLinkW;
6453}
6454
6455PyDoc_STRVAR(win_symlink__doc__,
6456"symlink(src, dst, target_is_directory=False)\n\n\
6457Create a symbolic link pointing to src named dst.\n\
6458target_is_directory is required if the target is to be interpreted as\n\
6459a directory.\n\
6460This function requires Windows 6.0 or greater, and raises a\n\
6461NotImplementedError otherwise.");
6462
6463static PyObject *
6464win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
6465{
6466 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
6467 PyObject *src, *dest;
6468 int target_is_directory = 0;
6469 DWORD res;
6470 WIN32_FILE_ATTRIBUTE_DATA src_info;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006471
Brian Curtind40e6f72010-07-08 21:39:08 +00006472 if (!check_CreateSymbolicLinkW())
6473 {
6474 /* raise NotImplementedError */
6475 return PyErr_Format(PyExc_NotImplementedError,
6476 "CreateSymbolicLinkW not found");
6477 }
6478 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
6479 kwlist, &src, &dest, &target_is_directory))
6480 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00006481
6482 if (win32_can_symlink == 0)
6483 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
6484
Brian Curtind40e6f72010-07-08 21:39:08 +00006485 if (!convert_to_unicode(&src)) { return NULL; }
6486 if (!convert_to_unicode(&dest)) {
6487 Py_DECREF(src);
6488 return NULL;
6489 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006490
Brian Curtind40e6f72010-07-08 21:39:08 +00006491 /* if src is a directory, ensure target_is_directory==1 */
6492 if(
6493 GetFileAttributesExW(
6494 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
6495 ))
6496 {
6497 target_is_directory = target_is_directory ||
6498 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
6499 }
6500
6501 Py_BEGIN_ALLOW_THREADS
6502 res = Py_CreateSymbolicLinkW(
6503 PyUnicode_AsUnicode(dest),
6504 PyUnicode_AsUnicode(src),
6505 target_is_directory);
6506 Py_END_ALLOW_THREADS
6507 Py_DECREF(src);
6508 Py_DECREF(dest);
6509 if (!res)
6510 {
6511 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
6512 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006513
Brian Curtind40e6f72010-07-08 21:39:08 +00006514 Py_INCREF(Py_None);
6515 return Py_None;
6516}
Brian Curtin52173d42010-12-02 18:29:18 +00006517#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006518
6519#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006520#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6521static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006522system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006523{
6524 ULONG value = 0;
6525
6526 Py_BEGIN_ALLOW_THREADS
6527 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6528 Py_END_ALLOW_THREADS
6529
6530 return value;
6531}
6532
6533static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006534posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006535{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006536 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00006537 return Py_BuildValue("ddddd",
6538 (double)0 /* t.tms_utime / HZ */,
6539 (double)0 /* t.tms_stime / HZ */,
6540 (double)0 /* t.tms_cutime / HZ */,
6541 (double)0 /* t.tms_cstime / HZ */,
6542 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006543}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006544#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00006545#define NEED_TICKS_PER_SECOND
6546static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006547static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006548posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006549{
Victor Stinner8c62be82010-05-06 00:08:46 +00006550 struct tms t;
6551 clock_t c;
6552 errno = 0;
6553 c = times(&t);
6554 if (c == (clock_t) -1)
6555 return posix_error();
6556 return Py_BuildValue("ddddd",
6557 (double)t.tms_utime / ticks_per_second,
6558 (double)t.tms_stime / ticks_per_second,
6559 (double)t.tms_cutime / ticks_per_second,
6560 (double)t.tms_cstime / ticks_per_second,
6561 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006562}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006563#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006564#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006565
6566
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006567#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006568#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006569static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006570posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006571{
Victor Stinner8c62be82010-05-06 00:08:46 +00006572 FILETIME create, exit, kernel, user;
6573 HANDLE hProc;
6574 hProc = GetCurrentProcess();
6575 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6576 /* The fields of a FILETIME structure are the hi and lo part
6577 of a 64-bit value expressed in 100 nanosecond units.
6578 1e7 is one second in such units; 1e-7 the inverse.
6579 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6580 */
6581 return Py_BuildValue(
6582 "ddddd",
6583 (double)(user.dwHighDateTime*429.4967296 +
6584 user.dwLowDateTime*1e-7),
6585 (double)(kernel.dwHighDateTime*429.4967296 +
6586 kernel.dwLowDateTime*1e-7),
6587 (double)0,
6588 (double)0,
6589 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006590}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006591#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006592
6593#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006594PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006595"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006596Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006597#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006598
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006599
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006600#ifdef HAVE_GETSID
6601PyDoc_STRVAR(posix_getsid__doc__,
6602"getsid(pid) -> sid\n\n\
6603Call the system call getsid().");
6604
6605static PyObject *
6606posix_getsid(PyObject *self, PyObject *args)
6607{
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 pid_t pid;
6609 int sid;
6610 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6611 return NULL;
6612 sid = getsid(pid);
6613 if (sid < 0)
6614 return posix_error();
6615 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006616}
6617#endif /* HAVE_GETSID */
6618
6619
Guido van Rossumb6775db1994-08-01 11:34:53 +00006620#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006621PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006622"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006624
Barry Warsaw53699e91996-12-10 23:23:01 +00006625static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006626posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006627{
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 if (setsid() < 0)
6629 return posix_error();
6630 Py_INCREF(Py_None);
6631 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006632}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006633#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006634
Guido van Rossumb6775db1994-08-01 11:34:53 +00006635#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006636PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006637"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006638Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006639
Barry Warsaw53699e91996-12-10 23:23:01 +00006640static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006641posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006642{
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 pid_t pid;
6644 int pgrp;
6645 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6646 return NULL;
6647 if (setpgid(pid, pgrp) < 0)
6648 return posix_error();
6649 Py_INCREF(Py_None);
6650 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006651}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006652#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006653
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006654
Guido van Rossumb6775db1994-08-01 11:34:53 +00006655#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006656PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006657"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006658Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006659
Barry Warsaw53699e91996-12-10 23:23:01 +00006660static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006661posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006662{
Victor Stinner8c62be82010-05-06 00:08:46 +00006663 int fd;
6664 pid_t pgid;
6665 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6666 return NULL;
6667 pgid = tcgetpgrp(fd);
6668 if (pgid < 0)
6669 return posix_error();
6670 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006671}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006672#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006674
Guido van Rossumb6775db1994-08-01 11:34:53 +00006675#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006676PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006677"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006678Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006679
Barry Warsaw53699e91996-12-10 23:23:01 +00006680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006681posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006682{
Victor Stinner8c62be82010-05-06 00:08:46 +00006683 int fd;
6684 pid_t pgid;
6685 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6686 return NULL;
6687 if (tcsetpgrp(fd, pgid) < 0)
6688 return posix_error();
6689 Py_INCREF(Py_None);
6690 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006691}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006692#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006693
Guido van Rossum687dd131993-05-17 08:34:16 +00006694/* Functions acting on file descriptors */
6695
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006696PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006697"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006698Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006699
Barry Warsaw53699e91996-12-10 23:23:01 +00006700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006701posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006702{
Victor Stinner8c62be82010-05-06 00:08:46 +00006703 PyObject *ofile;
6704 char *file;
6705 int flag;
6706 int mode = 0777;
6707 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006708
6709#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 PyUnicodeObject *po;
Victor Stinner26de69d2011-06-17 15:15:38 +02006711 if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 Py_BEGIN_ALLOW_THREADS
6713 /* PyUnicode_AS_UNICODE OK without thread
6714 lock as it is a simple dereference. */
6715 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6716 Py_END_ALLOW_THREADS
6717 if (fd < 0)
6718 return posix_error();
6719 return PyLong_FromLong((long)fd);
6720 }
6721 /* Drop the argument parsing error as narrow strings
6722 are also valid. */
6723 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006724#endif
6725
Victor Stinner26de69d2011-06-17 15:15:38 +02006726 if (!PyArg_ParseTuple(args, "O&i|i:open",
Victor Stinner8c62be82010-05-06 00:08:46 +00006727 PyUnicode_FSConverter, &ofile,
6728 &flag, &mode))
6729 return NULL;
6730 file = PyBytes_AsString(ofile);
6731 Py_BEGIN_ALLOW_THREADS
6732 fd = open(file, flag, mode);
6733 Py_END_ALLOW_THREADS
6734 if (fd < 0)
6735 return posix_error_with_allocated_filename(ofile);
6736 Py_DECREF(ofile);
6737 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006738}
6739
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006740
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006741PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006742"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006743Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006744
Barry Warsaw53699e91996-12-10 23:23:01 +00006745static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006746posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006747{
Victor Stinner8c62be82010-05-06 00:08:46 +00006748 int fd, res;
6749 if (!PyArg_ParseTuple(args, "i:close", &fd))
6750 return NULL;
6751 if (!_PyVerify_fd(fd))
6752 return posix_error();
6753 Py_BEGIN_ALLOW_THREADS
6754 res = close(fd);
6755 Py_END_ALLOW_THREADS
6756 if (res < 0)
6757 return posix_error();
6758 Py_INCREF(Py_None);
6759 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006760}
6761
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006762
Victor Stinner8c62be82010-05-06 00:08:46 +00006763PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00006764"closerange(fd_low, fd_high)\n\n\
6765Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6766
6767static PyObject *
6768posix_closerange(PyObject *self, PyObject *args)
6769{
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 int fd_from, fd_to, i;
6771 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6772 return NULL;
6773 Py_BEGIN_ALLOW_THREADS
6774 for (i = fd_from; i < fd_to; i++)
6775 if (_PyVerify_fd(i))
6776 close(i);
6777 Py_END_ALLOW_THREADS
6778 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00006779}
6780
6781
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006782PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006783"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006784Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006785
Barry Warsaw53699e91996-12-10 23:23:01 +00006786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006787posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006788{
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 int fd;
6790 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6791 return NULL;
6792 if (!_PyVerify_fd(fd))
6793 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00006795 if (fd < 0)
6796 return posix_error();
6797 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006798}
6799
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006800
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006801PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006802"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006803Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006804
Barry Warsaw53699e91996-12-10 23:23:01 +00006805static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006806posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006807{
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 int fd, fd2, res;
6809 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6810 return NULL;
6811 if (!_PyVerify_fd_dup2(fd, fd2))
6812 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006813 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 if (res < 0)
6815 return posix_error();
6816 Py_INCREF(Py_None);
6817 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006818}
6819
Ross Lagerwall7807c352011-03-17 20:20:30 +02006820#ifdef HAVE_LOCKF
6821PyDoc_STRVAR(posix_lockf__doc__,
6822"lockf(fd, cmd, len)\n\n\
6823Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
6824fd is an open file descriptor.\n\
6825cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
6826F_TEST.\n\
6827len specifies the section of the file to lock.");
6828
6829static PyObject *
6830posix_lockf(PyObject *self, PyObject *args)
6831{
6832 int fd, cmd, res;
6833 off_t len;
6834 if (!PyArg_ParseTuple(args, "iiO&:lockf",
6835 &fd, &cmd, _parse_off_t, &len))
6836 return NULL;
6837
6838 Py_BEGIN_ALLOW_THREADS
6839 res = lockf(fd, cmd, len);
6840 Py_END_ALLOW_THREADS
6841
6842 if (res < 0)
6843 return posix_error();
6844
6845 Py_RETURN_NONE;
6846}
6847#endif
6848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006849
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006850PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006851"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006852Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006853
Barry Warsaw53699e91996-12-10 23:23:01 +00006854static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006855posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006856{
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006858#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006860#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006862#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02006863 PyObject *posobj;
6864 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006866#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6868 switch (how) {
6869 case 0: how = SEEK_SET; break;
6870 case 1: how = SEEK_CUR; break;
6871 case 2: how = SEEK_END; break;
6872 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006873#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006874
Ross Lagerwall8e749672011-03-17 21:54:07 +02006875#if !defined(HAVE_LARGEFILE_SUPPORT)
6876 pos = PyLong_AsLong(posobj);
6877#else
6878 pos = PyLong_AsLongLong(posobj);
6879#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 if (PyErr_Occurred())
6881 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006882
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 if (!_PyVerify_fd(fd))
6884 return posix_error();
6885 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006886#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006888#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006890#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006891 Py_END_ALLOW_THREADS
6892 if (res < 0)
6893 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006894
6895#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006897#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006899#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006900}
6901
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006902
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006903PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006904"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006905Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006906
Barry Warsaw53699e91996-12-10 23:23:01 +00006907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006908posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006909{
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 int fd, size;
6911 Py_ssize_t n;
6912 PyObject *buffer;
6913 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6914 return NULL;
6915 if (size < 0) {
6916 errno = EINVAL;
6917 return posix_error();
6918 }
6919 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
6920 if (buffer == NULL)
6921 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00006922 if (!_PyVerify_fd(fd)) {
6923 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00006924 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00006925 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 Py_BEGIN_ALLOW_THREADS
6927 n = read(fd, PyBytes_AS_STRING(buffer), size);
6928 Py_END_ALLOW_THREADS
6929 if (n < 0) {
6930 Py_DECREF(buffer);
6931 return posix_error();
6932 }
6933 if (n != size)
6934 _PyBytes_Resize(&buffer, n);
6935 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006936}
6937
Ross Lagerwall7807c352011-03-17 20:20:30 +02006938#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
6939 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00006940static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006941iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
6942{
6943 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00006944 Py_ssize_t blen, total = 0;
6945
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006946 *iov = PyMem_New(struct iovec, cnt);
6947 if (*iov == NULL) {
6948 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00006949 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006950 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00006951
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006952 *buf = PyMem_New(Py_buffer, cnt);
6953 if (*buf == NULL) {
6954 PyMem_Del(*iov);
6955 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00006956 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006957 }
6958
6959 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02006960 PyObject *item = PySequence_GetItem(seq, i);
6961 if (item == NULL)
6962 goto fail;
6963 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
6964 Py_DECREF(item);
6965 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006966 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02006967 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006968 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00006969 blen = (*buf)[i].len;
6970 (*iov)[i].iov_len = blen;
6971 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006972 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00006973 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02006974
6975fail:
6976 PyMem_Del(*iov);
6977 for (j = 0; j < i; j++) {
6978 PyBuffer_Release(&(*buf)[j]);
6979 }
6980 PyMem_Del(*buf);
6981 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006982}
6983
6984static void
6985iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
6986{
6987 int i;
6988 PyMem_Del(iov);
6989 for (i = 0; i < cnt; i++) {
6990 PyBuffer_Release(&buf[i]);
6991 }
6992 PyMem_Del(buf);
6993}
6994#endif
6995
Ross Lagerwall7807c352011-03-17 20:20:30 +02006996#ifdef HAVE_READV
6997PyDoc_STRVAR(posix_readv__doc__,
6998"readv(fd, buffers) -> bytesread\n\n\
6999Read from a file descriptor into a number of writable buffers. buffers\n\
7000is an arbitrary sequence of writable buffers.\n\
7001Returns the total number of bytes read.");
7002
7003static PyObject *
7004posix_readv(PyObject *self, PyObject *args)
7005{
7006 int fd, cnt;
7007 Py_ssize_t n;
7008 PyObject *seq;
7009 struct iovec *iov;
7010 Py_buffer *buf;
7011
7012 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7013 return NULL;
7014 if (!PySequence_Check(seq)) {
7015 PyErr_SetString(PyExc_TypeError,
7016 "readv() arg 2 must be a sequence");
7017 return NULL;
7018 }
7019 cnt = PySequence_Size(seq);
7020
7021 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7022 return NULL;
7023
7024 Py_BEGIN_ALLOW_THREADS
7025 n = readv(fd, iov, cnt);
7026 Py_END_ALLOW_THREADS
7027
7028 iov_cleanup(iov, buf, cnt);
7029 return PyLong_FromSsize_t(n);
7030}
7031#endif
7032
7033#ifdef HAVE_PREAD
7034PyDoc_STRVAR(posix_pread__doc__,
7035"pread(fd, buffersize, offset) -> string\n\n\
7036Read from a file descriptor, fd, at a position of offset. It will read up\n\
7037to buffersize number of bytes. The file offset remains unchanged.");
7038
7039static PyObject *
7040posix_pread(PyObject *self, PyObject *args)
7041{
7042 int fd, size;
7043 off_t offset;
7044 Py_ssize_t n;
7045 PyObject *buffer;
7046 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7047 return NULL;
7048
7049 if (size < 0) {
7050 errno = EINVAL;
7051 return posix_error();
7052 }
7053 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7054 if (buffer == NULL)
7055 return NULL;
7056 if (!_PyVerify_fd(fd)) {
7057 Py_DECREF(buffer);
7058 return posix_error();
7059 }
7060 Py_BEGIN_ALLOW_THREADS
7061 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7062 Py_END_ALLOW_THREADS
7063 if (n < 0) {
7064 Py_DECREF(buffer);
7065 return posix_error();
7066 }
7067 if (n != size)
7068 _PyBytes_Resize(&buffer, n);
7069 return buffer;
7070}
7071#endif
7072
7073PyDoc_STRVAR(posix_write__doc__,
7074"write(fd, string) -> byteswritten\n\n\
7075Write a string to a file descriptor.");
7076
7077static PyObject *
7078posix_write(PyObject *self, PyObject *args)
7079{
7080 Py_buffer pbuf;
7081 int fd;
7082 Py_ssize_t size, len;
7083
7084 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7085 return NULL;
7086 if (!_PyVerify_fd(fd)) {
7087 PyBuffer_Release(&pbuf);
7088 return posix_error();
7089 }
7090 len = pbuf.len;
7091 Py_BEGIN_ALLOW_THREADS
7092#if defined(MS_WIN64) || defined(MS_WINDOWS)
7093 if (len > INT_MAX)
7094 len = INT_MAX;
7095 size = write(fd, pbuf.buf, (int)len);
7096#else
7097 size = write(fd, pbuf.buf, len);
7098#endif
7099 Py_END_ALLOW_THREADS
7100 PyBuffer_Release(&pbuf);
7101 if (size < 0)
7102 return posix_error();
7103 return PyLong_FromSsize_t(size);
7104}
7105
7106#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007107PyDoc_STRVAR(posix_sendfile__doc__,
7108"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7109sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7110 -> byteswritten\n\
7111Copy nbytes bytes from file descriptor in to file descriptor out.");
7112
7113static PyObject *
7114posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7115{
7116 int in, out;
7117 Py_ssize_t ret;
7118 off_t offset;
7119
7120#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7121#ifndef __APPLE__
7122 Py_ssize_t len;
7123#endif
7124 PyObject *headers = NULL, *trailers = NULL;
7125 Py_buffer *hbuf, *tbuf;
7126 off_t sbytes;
7127 struct sf_hdtr sf;
7128 int flags = 0;
7129 sf.headers = NULL;
7130 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007131 static char *keywords[] = {"out", "in",
7132 "offset", "count",
7133 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007134
7135#ifdef __APPLE__
7136 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007137 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007138#else
7139 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007140 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007141#endif
7142 &headers, &trailers, &flags))
7143 return NULL;
7144 if (headers != NULL) {
7145 if (!PySequence_Check(headers)) {
7146 PyErr_SetString(PyExc_TypeError,
7147 "sendfile() headers must be a sequence or None");
7148 return NULL;
7149 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007150 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007151 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007152 if (sf.hdr_cnt > 0 &&
7153 !(i = iov_setup(&(sf.headers), &hbuf,
7154 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007155 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007156#ifdef __APPLE__
7157 sbytes += i;
7158#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007159 }
7160 }
7161 if (trailers != NULL) {
7162 if (!PySequence_Check(trailers)) {
7163 PyErr_SetString(PyExc_TypeError,
7164 "sendfile() trailers must be a sequence or None");
7165 return NULL;
7166 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007167 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007168 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007169 if (sf.trl_cnt > 0 &&
7170 !(i = iov_setup(&(sf.trailers), &tbuf,
7171 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007172 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007173#ifdef __APPLE__
7174 sbytes += i;
7175#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007176 }
7177 }
7178
7179 Py_BEGIN_ALLOW_THREADS
7180#ifdef __APPLE__
7181 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7182#else
7183 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7184#endif
7185 Py_END_ALLOW_THREADS
7186
7187 if (sf.headers != NULL)
7188 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7189 if (sf.trailers != NULL)
7190 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7191
7192 if (ret < 0) {
7193 if ((errno == EAGAIN) || (errno == EBUSY)) {
7194 if (sbytes != 0) {
7195 // some data has been sent
7196 goto done;
7197 }
7198 else {
7199 // no data has been sent; upper application is supposed
7200 // to retry on EAGAIN or EBUSY
7201 return posix_error();
7202 }
7203 }
7204 return posix_error();
7205 }
7206 goto done;
7207
7208done:
7209 #if !defined(HAVE_LARGEFILE_SUPPORT)
7210 return Py_BuildValue("l", sbytes);
7211 #else
7212 return Py_BuildValue("L", sbytes);
7213 #endif
7214
7215#else
7216 Py_ssize_t count;
7217 PyObject *offobj;
7218 static char *keywords[] = {"out", "in",
7219 "offset", "count", NULL};
7220 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7221 keywords, &out, &in, &offobj, &count))
7222 return NULL;
7223#ifdef linux
7224 if (offobj == Py_None) {
7225 Py_BEGIN_ALLOW_THREADS
7226 ret = sendfile(out, in, NULL, count);
7227 Py_END_ALLOW_THREADS
7228 if (ret < 0)
7229 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007230 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007231 }
7232#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007233 if (!_parse_off_t(offobj, &offset))
7234 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007235 Py_BEGIN_ALLOW_THREADS
7236 ret = sendfile(out, in, &offset, count);
7237 Py_END_ALLOW_THREADS
7238 if (ret < 0)
7239 return posix_error();
7240 return Py_BuildValue("n", ret);
7241#endif
7242}
7243#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007244
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007245PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007246"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007247Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007248
Barry Warsaw53699e91996-12-10 23:23:01 +00007249static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007250posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007251{
Victor Stinner8c62be82010-05-06 00:08:46 +00007252 int fd;
7253 STRUCT_STAT st;
7254 int res;
7255 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
7256 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007257#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007258 /* on OpenVMS we must ensure that all bytes are written to the file */
7259 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007260#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007261 if (!_PyVerify_fd(fd))
7262 return posix_error();
7263 Py_BEGIN_ALLOW_THREADS
7264 res = FSTAT(fd, &st);
7265 Py_END_ALLOW_THREADS
7266 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007267#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007268 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00007269#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007270 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007271#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007272 }
Tim Peters5aa91602002-01-30 05:46:57 +00007273
Victor Stinner8c62be82010-05-06 00:08:46 +00007274 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007275}
7276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007277PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007278"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007279Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007280connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007281
7282static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007283posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007284{
Victor Stinner8c62be82010-05-06 00:08:46 +00007285 int fd;
7286 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7287 return NULL;
7288 if (!_PyVerify_fd(fd))
7289 return PyBool_FromLong(0);
7290 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007291}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007292
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007293#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007294PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007295"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007296Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007297
Barry Warsaw53699e91996-12-10 23:23:01 +00007298static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007299posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007300{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007301#if defined(PYOS_OS2)
7302 HFILE read, write;
7303 APIRET rc;
7304
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007305 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007306 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007307 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007308
7309 return Py_BuildValue("(ii)", read, write);
7310#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007311#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007312 int fds[2];
7313 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007314 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007315 if (res != 0)
7316 return posix_error();
7317 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007318#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007319 HANDLE read, write;
7320 int read_fd, write_fd;
7321 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007322 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007323 if (!ok)
7324 return win32_error("CreatePipe", NULL);
7325 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7326 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7327 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007328#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007329#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007330}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007331#endif /* HAVE_PIPE */
7332
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007333#ifdef HAVE_PIPE2
7334PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007335"pipe2(flags) -> (read_end, write_end)\n\n\
7336Create a pipe with flags set atomically.\n\
7337flags can be constructed by ORing together one or more of these values:\n\
7338O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007339");
7340
7341static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007342posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007343{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007344 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007345 int fds[2];
7346 int res;
7347
Charles-François Natali368f34b2011-06-06 19:49:47 +02007348 flags = PyLong_AsLong(arg);
7349 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007350 return NULL;
7351
7352 res = pipe2(fds, flags);
7353 if (res != 0)
7354 return posix_error();
7355 return Py_BuildValue("(ii)", fds[0], fds[1]);
7356}
7357#endif /* HAVE_PIPE2 */
7358
Ross Lagerwall7807c352011-03-17 20:20:30 +02007359#ifdef HAVE_WRITEV
7360PyDoc_STRVAR(posix_writev__doc__,
7361"writev(fd, buffers) -> byteswritten\n\n\
7362Write the contents of buffers to a file descriptor, where buffers is an\n\
7363arbitrary sequence of buffers.\n\
7364Returns the total bytes written.");
7365
7366static PyObject *
7367posix_writev(PyObject *self, PyObject *args)
7368{
7369 int fd, cnt;
7370 Py_ssize_t res;
7371 PyObject *seq;
7372 struct iovec *iov;
7373 Py_buffer *buf;
7374 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7375 return NULL;
7376 if (!PySequence_Check(seq)) {
7377 PyErr_SetString(PyExc_TypeError,
7378 "writev() arg 2 must be a sequence");
7379 return NULL;
7380 }
7381 cnt = PySequence_Size(seq);
7382
7383 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7384 return NULL;
7385 }
7386
7387 Py_BEGIN_ALLOW_THREADS
7388 res = writev(fd, iov, cnt);
7389 Py_END_ALLOW_THREADS
7390
7391 iov_cleanup(iov, buf, cnt);
7392 return PyLong_FromSsize_t(res);
7393}
7394#endif
7395
7396#ifdef HAVE_PWRITE
7397PyDoc_STRVAR(posix_pwrite__doc__,
7398"pwrite(fd, string, offset) -> byteswritten\n\n\
7399Write string to a file descriptor, fd, from offset, leaving the file\n\
7400offset unchanged.");
7401
7402static PyObject *
7403posix_pwrite(PyObject *self, PyObject *args)
7404{
7405 Py_buffer pbuf;
7406 int fd;
7407 off_t offset;
7408 Py_ssize_t size;
7409
7410 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7411 return NULL;
7412
7413 if (!_PyVerify_fd(fd)) {
7414 PyBuffer_Release(&pbuf);
7415 return posix_error();
7416 }
7417 Py_BEGIN_ALLOW_THREADS
7418 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7419 Py_END_ALLOW_THREADS
7420 PyBuffer_Release(&pbuf);
7421 if (size < 0)
7422 return posix_error();
7423 return PyLong_FromSsize_t(size);
7424}
7425#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007426
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007427#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007428PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007429"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007430Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007431
Barry Warsaw53699e91996-12-10 23:23:01 +00007432static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007433posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007434{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007435 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007436 char *filename;
7437 int mode = 0666;
7438 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007439 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
7440 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00007441 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007442 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007443 Py_BEGIN_ALLOW_THREADS
7444 res = mkfifo(filename, mode);
7445 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007446 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007447 if (res < 0)
7448 return posix_error();
7449 Py_INCREF(Py_None);
7450 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007451}
7452#endif
7453
7454
Neal Norwitz11690112002-07-30 01:08:28 +00007455#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007456PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007457"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007458Create a filesystem node (file, device special file or named pipe)\n\
7459named filename. mode specifies both the permissions to use and the\n\
7460type of node to be created, being combined (bitwise OR) with one of\n\
7461S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007462device defines the newly created device special file (probably using\n\
7463os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007464
7465
7466static PyObject *
7467posix_mknod(PyObject *self, PyObject *args)
7468{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007469 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007470 char *filename;
7471 int mode = 0600;
7472 int device = 0;
7473 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007474 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
7475 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00007476 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007477 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007478 Py_BEGIN_ALLOW_THREADS
7479 res = mknod(filename, mode, device);
7480 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007481 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007482 if (res < 0)
7483 return posix_error();
7484 Py_INCREF(Py_None);
7485 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007486}
7487#endif
7488
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007489#ifdef HAVE_DEVICE_MACROS
7490PyDoc_STRVAR(posix_major__doc__,
7491"major(device) -> major number\n\
7492Extracts a device major number from a raw device number.");
7493
7494static PyObject *
7495posix_major(PyObject *self, PyObject *args)
7496{
Victor Stinner8c62be82010-05-06 00:08:46 +00007497 int device;
7498 if (!PyArg_ParseTuple(args, "i:major", &device))
7499 return NULL;
7500 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007501}
7502
7503PyDoc_STRVAR(posix_minor__doc__,
7504"minor(device) -> minor number\n\
7505Extracts a device minor number from a raw device number.");
7506
7507static PyObject *
7508posix_minor(PyObject *self, PyObject *args)
7509{
Victor Stinner8c62be82010-05-06 00:08:46 +00007510 int device;
7511 if (!PyArg_ParseTuple(args, "i:minor", &device))
7512 return NULL;
7513 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007514}
7515
7516PyDoc_STRVAR(posix_makedev__doc__,
7517"makedev(major, minor) -> device number\n\
7518Composes a raw device number from the major and minor device numbers.");
7519
7520static PyObject *
7521posix_makedev(PyObject *self, PyObject *args)
7522{
Victor Stinner8c62be82010-05-06 00:08:46 +00007523 int major, minor;
7524 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7525 return NULL;
7526 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007527}
7528#endif /* device macros */
7529
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007530
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007531#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007532PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007533"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007534Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007535
Barry Warsaw53699e91996-12-10 23:23:01 +00007536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007537posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007538{
Victor Stinner8c62be82010-05-06 00:08:46 +00007539 int fd;
7540 off_t length;
7541 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007542
Ross Lagerwall7807c352011-03-17 20:20:30 +02007543 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007544 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007545
Victor Stinner8c62be82010-05-06 00:08:46 +00007546 Py_BEGIN_ALLOW_THREADS
7547 res = ftruncate(fd, length);
7548 Py_END_ALLOW_THREADS
7549 if (res < 0)
7550 return posix_error();
7551 Py_INCREF(Py_None);
7552 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007553}
7554#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007555
Ross Lagerwall7807c352011-03-17 20:20:30 +02007556#ifdef HAVE_TRUNCATE
7557PyDoc_STRVAR(posix_truncate__doc__,
7558"truncate(path, length)\n\n\
7559Truncate the file given by path to length bytes.");
7560
7561static PyObject *
7562posix_truncate(PyObject *self, PyObject *args)
7563{
7564 PyObject *opath;
7565 const char *path;
7566 off_t length;
7567 int res;
7568
7569 if (!PyArg_ParseTuple(args, "O&O&:truncate",
7570 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
7571 return NULL;
7572 path = PyBytes_AsString(opath);
7573
7574 Py_BEGIN_ALLOW_THREADS
7575 res = truncate(path, length);
7576 Py_END_ALLOW_THREADS
7577 Py_DECREF(opath);
7578 if (res < 0)
7579 return posix_error();
7580 Py_RETURN_NONE;
7581}
7582#endif
7583
7584#ifdef HAVE_POSIX_FALLOCATE
7585PyDoc_STRVAR(posix_posix_fallocate__doc__,
7586"posix_fallocate(fd, offset, len)\n\n\
7587Ensures that enough disk space is allocated for the file specified by fd\n\
7588starting from offset and continuing for len bytes.");
7589
7590static PyObject *
7591posix_posix_fallocate(PyObject *self, PyObject *args)
7592{
7593 off_t len, offset;
7594 int res, fd;
7595
7596 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7597 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7598 return NULL;
7599
7600 Py_BEGIN_ALLOW_THREADS
7601 res = posix_fallocate(fd, offset, len);
7602 Py_END_ALLOW_THREADS
7603 if (res != 0) {
7604 errno = res;
7605 return posix_error();
7606 }
7607 Py_RETURN_NONE;
7608}
7609#endif
7610
7611#ifdef HAVE_POSIX_FADVISE
7612PyDoc_STRVAR(posix_posix_fadvise__doc__,
7613"posix_fadvise(fd, offset, len, advice)\n\n\
7614Announces an intention to access data in a specific pattern thus allowing\n\
7615the kernel to make optimizations.\n\
7616The advice applies to the region of the file specified by fd starting at\n\
7617offset and continuing for len bytes.\n\
7618advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7619POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7620POSIX_FADV_DONTNEED.");
7621
7622static PyObject *
7623posix_posix_fadvise(PyObject *self, PyObject *args)
7624{
7625 off_t len, offset;
7626 int res, fd, advice;
7627
7628 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
7629 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
7630 return NULL;
7631
7632 Py_BEGIN_ALLOW_THREADS
7633 res = posix_fadvise(fd, offset, len, advice);
7634 Py_END_ALLOW_THREADS
7635 if (res != 0) {
7636 errno = res;
7637 return posix_error();
7638 }
7639 Py_RETURN_NONE;
7640}
7641#endif
7642
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007643#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007644PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007645"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007646Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007647
Fred Drake762e2061999-08-26 17:23:54 +00007648/* Save putenv() parameters as values here, so we can collect them when they
7649 * get re-set with another call for the same key. */
7650static PyObject *posix_putenv_garbage;
7651
Tim Peters5aa91602002-01-30 05:46:57 +00007652static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007653posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007654{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007655#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007656 wchar_t *s1, *s2;
7657 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007658#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007659 PyObject *os1, *os2;
7660 char *s1, *s2;
7661 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007662#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007663 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007665
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007666#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007667 if (!PyArg_ParseTuple(args,
7668 "uu:putenv",
7669 &s1, &s2))
7670 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00007671#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007672 if (!PyArg_ParseTuple(args,
7673 "O&O&:putenv",
7674 PyUnicode_FSConverter, &os1,
7675 PyUnicode_FSConverter, &os2))
7676 return NULL;
7677 s1 = PyBytes_AsString(os1);
7678 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007679#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007680
7681#if defined(PYOS_OS2)
7682 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7683 APIRET rc;
7684
Guido van Rossumd48f2521997-12-05 22:19:34 +00007685 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00007686 if (rc != NO_ERROR) {
7687 os2_error(rc);
7688 goto error;
7689 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007690
7691 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7692 APIRET rc;
7693
Guido van Rossumd48f2521997-12-05 22:19:34 +00007694 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00007695 if (rc != NO_ERROR) {
7696 os2_error(rc);
7697 goto error;
7698 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007699 } else {
7700#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007701 /* XXX This can leak memory -- not easy to fix :-( */
7702 /* len includes space for a trailing \0; the size arg to
7703 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007704#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 len = wcslen(s1) + wcslen(s2) + 2;
7706 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007707#else
Victor Stinner84ae1182010-05-06 22:05:07 +00007708 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00007709 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007710#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007711 if (newstr == NULL) {
7712 PyErr_NoMemory();
7713 goto error;
7714 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007715#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 newenv = PyUnicode_AsUnicode(newstr);
7717 _snwprintf(newenv, len, L"%s=%s", s1, s2);
7718 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007720 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007721 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007722#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007723 newenv = PyBytes_AS_STRING(newstr);
7724 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7725 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007727 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007729#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007730
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 /* Install the first arg and newstr in posix_putenv_garbage;
7732 * this will cause previous value to be collected. This has to
7733 * happen after the real putenv() call because the old value
7734 * was still accessible until then. */
7735 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00007736#ifdef MS_WINDOWS
7737 PyTuple_GET_ITEM(args, 0),
7738#else
7739 os1,
7740#endif
7741 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007742 /* really not much we can do; just leak */
7743 PyErr_Clear();
7744 }
7745 else {
7746 Py_DECREF(newstr);
7747 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007748
7749#if defined(PYOS_OS2)
7750 }
7751#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007752
Martin v. Löwis011e8422009-05-05 04:43:17 +00007753#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 Py_DECREF(os1);
7755 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007756#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007757 Py_RETURN_NONE;
7758
7759error:
7760#ifndef MS_WINDOWS
7761 Py_DECREF(os1);
7762 Py_DECREF(os2);
7763#endif
7764 Py_XDECREF(newstr);
7765 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007766}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007767#endif /* putenv */
7768
Guido van Rossumc524d952001-10-19 01:31:59 +00007769#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007770PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007771"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007772Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007773
7774static PyObject *
7775posix_unsetenv(PyObject *self, PyObject *args)
7776{
Victor Stinner84ae1182010-05-06 22:05:07 +00007777#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00007779
Victor Stinner8c62be82010-05-06 00:08:46 +00007780 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7781 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00007782#else
7783 PyObject *os1;
7784 char *s1;
7785
7786 if (!PyArg_ParseTuple(args, "O&:unsetenv",
7787 PyUnicode_FSConverter, &os1))
7788 return NULL;
7789 s1 = PyBytes_AsString(os1);
7790#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007791
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00007793
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 /* Remove the key from posix_putenv_garbage;
7795 * this will cause it to be collected. This has to
7796 * happen after the real unsetenv() call because the
7797 * old value was still accessible until then.
7798 */
7799 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00007800#ifdef MS_WINDOWS
7801 PyTuple_GET_ITEM(args, 0)
7802#else
7803 os1
7804#endif
7805 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007806 /* really not much we can do; just leak */
7807 PyErr_Clear();
7808 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007809
Victor Stinner84ae1182010-05-06 22:05:07 +00007810#ifndef MS_WINDOWS
7811 Py_DECREF(os1);
7812#endif
7813 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00007814}
7815#endif /* unsetenv */
7816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007817PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007818"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007819Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007820
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007822posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007823{
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 int code;
7825 char *message;
7826 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7827 return NULL;
7828 message = strerror(code);
7829 if (message == NULL) {
7830 PyErr_SetString(PyExc_ValueError,
7831 "strerror() argument out of range");
7832 return NULL;
7833 }
7834 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007835}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007836
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007837
Guido van Rossumc9641791998-08-04 15:26:23 +00007838#ifdef HAVE_SYS_WAIT_H
7839
Fred Drake106c1a02002-04-23 15:58:02 +00007840#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007841PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007842"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007843Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007844
7845static PyObject *
7846posix_WCOREDUMP(PyObject *self, PyObject *args)
7847{
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 WAIT_TYPE status;
7849 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007850
Victor Stinner8c62be82010-05-06 00:08:46 +00007851 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7852 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007853
Victor Stinner8c62be82010-05-06 00:08:46 +00007854 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007855}
7856#endif /* WCOREDUMP */
7857
7858#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007859PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007860"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007861Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007862job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007863
7864static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007865posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007866{
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 WAIT_TYPE status;
7868 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007869
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7871 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007872
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007874}
7875#endif /* WIFCONTINUED */
7876
Guido van Rossumc9641791998-08-04 15:26:23 +00007877#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007878PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007879"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007880Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007881
7882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007883posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007884{
Victor Stinner8c62be82010-05-06 00:08:46 +00007885 WAIT_TYPE status;
7886 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007887
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7889 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007890
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007892}
7893#endif /* WIFSTOPPED */
7894
7895#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007896PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007897"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007898Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007899
7900static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007901posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007902{
Victor Stinner8c62be82010-05-06 00:08:46 +00007903 WAIT_TYPE status;
7904 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007905
Victor Stinner8c62be82010-05-06 00:08:46 +00007906 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7907 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007908
Victor Stinner8c62be82010-05-06 00:08:46 +00007909 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007910}
7911#endif /* WIFSIGNALED */
7912
7913#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007914PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007915"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007916Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007917system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007918
7919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007920posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007921{
Victor Stinner8c62be82010-05-06 00:08:46 +00007922 WAIT_TYPE status;
7923 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007924
Victor Stinner8c62be82010-05-06 00:08:46 +00007925 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7926 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007927
Victor Stinner8c62be82010-05-06 00:08:46 +00007928 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007929}
7930#endif /* WIFEXITED */
7931
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007932#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007933PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007934"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007935Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007936
7937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007938posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007939{
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 WAIT_TYPE status;
7941 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007942
Victor Stinner8c62be82010-05-06 00:08:46 +00007943 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7944 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007945
Victor Stinner8c62be82010-05-06 00:08:46 +00007946 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007947}
7948#endif /* WEXITSTATUS */
7949
7950#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007951PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007952"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007953Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007954value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007955
7956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007957posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007958{
Victor Stinner8c62be82010-05-06 00:08:46 +00007959 WAIT_TYPE status;
7960 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007961
Victor Stinner8c62be82010-05-06 00:08:46 +00007962 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7963 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007964
Victor Stinner8c62be82010-05-06 00:08:46 +00007965 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007966}
7967#endif /* WTERMSIG */
7968
7969#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007970PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007971"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007972Return the signal that stopped the process that provided\n\
7973the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007974
7975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007976posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007977{
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 WAIT_TYPE status;
7979 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007980
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7982 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007983
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007985}
7986#endif /* WSTOPSIG */
7987
7988#endif /* HAVE_SYS_WAIT_H */
7989
7990
Thomas Wouters477c8d52006-05-27 19:21:47 +00007991#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007992#ifdef _SCO_DS
7993/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7994 needed definitions in sys/statvfs.h */
7995#define _SVID3
7996#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007997#include <sys/statvfs.h>
7998
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007999static PyObject*
8000_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8002 if (v == NULL)
8003 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008004
8005#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008006 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8007 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8008 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8009 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8010 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8011 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8012 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8013 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8014 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8015 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008016#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8018 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8019 PyStructSequence_SET_ITEM(v, 2,
8020 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8021 PyStructSequence_SET_ITEM(v, 3,
8022 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8023 PyStructSequence_SET_ITEM(v, 4,
8024 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8025 PyStructSequence_SET_ITEM(v, 5,
8026 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8027 PyStructSequence_SET_ITEM(v, 6,
8028 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8029 PyStructSequence_SET_ITEM(v, 7,
8030 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8031 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8032 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008033#endif
8034
Victor Stinner8c62be82010-05-06 00:08:46 +00008035 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008036}
8037
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008038PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008039"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008040Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008041
8042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008043posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008044{
Victor Stinner8c62be82010-05-06 00:08:46 +00008045 int fd, res;
8046 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008047
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8049 return NULL;
8050 Py_BEGIN_ALLOW_THREADS
8051 res = fstatvfs(fd, &st);
8052 Py_END_ALLOW_THREADS
8053 if (res != 0)
8054 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008055
Victor Stinner8c62be82010-05-06 00:08:46 +00008056 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008057}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008058#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008059
8060
Thomas Wouters477c8d52006-05-27 19:21:47 +00008061#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008062#include <sys/statvfs.h>
8063
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008064PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008065"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008066Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008067
8068static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008069posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008070{
Victor Stinner8c62be82010-05-06 00:08:46 +00008071 char *path;
8072 int res;
8073 struct statvfs st;
8074 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
8075 return NULL;
8076 Py_BEGIN_ALLOW_THREADS
8077 res = statvfs(path, &st);
8078 Py_END_ALLOW_THREADS
8079 if (res != 0)
8080 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008081
Victor Stinner8c62be82010-05-06 00:08:46 +00008082 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008083}
8084#endif /* HAVE_STATVFS */
8085
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008086#ifdef MS_WINDOWS
8087PyDoc_STRVAR(win32__getdiskusage__doc__,
8088"_getdiskusage(path) -> (total, free)\n\n\
8089Return disk usage statistics about the given path as (total, free) tuple.");
8090
8091static PyObject *
8092win32__getdiskusage(PyObject *self, PyObject *args)
8093{
8094 BOOL retval;
8095 ULARGE_INTEGER _, total, free;
8096 LPCTSTR path;
8097
8098 if (! PyArg_ParseTuple(args, "s", &path))
8099 return NULL;
8100
8101 Py_BEGIN_ALLOW_THREADS
8102 retval = GetDiskFreeSpaceEx(path, &_, &total, &free);
8103 Py_END_ALLOW_THREADS
8104 if (retval == 0)
8105 return PyErr_SetFromWindowsErr(0);
8106
8107 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8108}
8109#endif
8110
8111
Fred Drakec9680921999-12-13 16:37:25 +00008112/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8113 * It maps strings representing configuration variable names to
8114 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008115 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008116 * rarely-used constants. There are three separate tables that use
8117 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008118 *
8119 * This code is always included, even if none of the interfaces that
8120 * need it are included. The #if hackery needed to avoid it would be
8121 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008122 */
8123struct constdef {
8124 char *name;
8125 long value;
8126};
8127
Fred Drake12c6e2d1999-12-14 21:25:03 +00008128static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008129conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008130 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008131{
Christian Heimes217cfd12007-12-02 14:31:20 +00008132 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008133 *valuep = PyLong_AS_LONG(arg);
8134 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008135 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008136 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008137 /* look up the value in the table using a binary search */
8138 size_t lo = 0;
8139 size_t mid;
8140 size_t hi = tablesize;
8141 int cmp;
8142 const char *confname;
8143 if (!PyUnicode_Check(arg)) {
8144 PyErr_SetString(PyExc_TypeError,
8145 "configuration names must be strings or integers");
8146 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008147 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008148 confname = _PyUnicode_AsString(arg);
8149 if (confname == NULL)
8150 return 0;
8151 while (lo < hi) {
8152 mid = (lo + hi) / 2;
8153 cmp = strcmp(confname, table[mid].name);
8154 if (cmp < 0)
8155 hi = mid;
8156 else if (cmp > 0)
8157 lo = mid + 1;
8158 else {
8159 *valuep = table[mid].value;
8160 return 1;
8161 }
8162 }
8163 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8164 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008165 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008166}
8167
8168
8169#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8170static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008171#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008172 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008173#endif
8174#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008175 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008176#endif
Fred Drakec9680921999-12-13 16:37:25 +00008177#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008178 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008179#endif
8180#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008181 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008182#endif
8183#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008184 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008185#endif
8186#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008187 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008188#endif
8189#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008191#endif
8192#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008194#endif
8195#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008196 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008197#endif
8198#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008199 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008200#endif
8201#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008203#endif
8204#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008205 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008206#endif
8207#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008209#endif
8210#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008211 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008212#endif
8213#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008214 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008215#endif
8216#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008217 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008218#endif
8219#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008220 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008221#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008222#ifdef _PC_ACL_ENABLED
8223 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8224#endif
8225#ifdef _PC_MIN_HOLE_SIZE
8226 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8227#endif
8228#ifdef _PC_ALLOC_SIZE_MIN
8229 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8230#endif
8231#ifdef _PC_REC_INCR_XFER_SIZE
8232 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8233#endif
8234#ifdef _PC_REC_MAX_XFER_SIZE
8235 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8236#endif
8237#ifdef _PC_REC_MIN_XFER_SIZE
8238 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8239#endif
8240#ifdef _PC_REC_XFER_ALIGN
8241 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8242#endif
8243#ifdef _PC_SYMLINK_MAX
8244 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8245#endif
8246#ifdef _PC_XATTR_ENABLED
8247 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8248#endif
8249#ifdef _PC_XATTR_EXISTS
8250 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8251#endif
8252#ifdef _PC_TIMESTAMP_RESOLUTION
8253 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8254#endif
Fred Drakec9680921999-12-13 16:37:25 +00008255};
8256
Fred Drakec9680921999-12-13 16:37:25 +00008257static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008258conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008259{
8260 return conv_confname(arg, valuep, posix_constants_pathconf,
8261 sizeof(posix_constants_pathconf)
8262 / sizeof(struct constdef));
8263}
8264#endif
8265
8266#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008267PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008268"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008269Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008270If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008271
8272static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008273posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008274{
8275 PyObject *result = NULL;
8276 int name, fd;
8277
Fred Drake12c6e2d1999-12-14 21:25:03 +00008278 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8279 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008280 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008281
Stefan Krah0e803b32010-11-26 16:16:47 +00008282 errno = 0;
8283 limit = fpathconf(fd, name);
8284 if (limit == -1 && errno != 0)
8285 posix_error();
8286 else
8287 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008288 }
8289 return result;
8290}
8291#endif
8292
8293
8294#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008295PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008296"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008297Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008298If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008299
8300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008301posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008302{
8303 PyObject *result = NULL;
8304 int name;
8305 char *path;
8306
8307 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
8308 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008309 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008310
Victor Stinner8c62be82010-05-06 00:08:46 +00008311 errno = 0;
8312 limit = pathconf(path, name);
8313 if (limit == -1 && errno != 0) {
8314 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008315 /* could be a path or name problem */
8316 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008317 else
Stefan Krah99439262010-11-26 12:58:05 +00008318 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008319 }
8320 else
8321 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008322 }
8323 return result;
8324}
8325#endif
8326
8327#ifdef HAVE_CONFSTR
8328static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008329#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008330 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008331#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008332#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008333 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008334#endif
8335#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008336 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008337#endif
Fred Draked86ed291999-12-15 15:34:33 +00008338#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008339 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008340#endif
8341#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008342 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008343#endif
8344#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008345 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008346#endif
8347#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008348 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008349#endif
Fred Drakec9680921999-12-13 16:37:25 +00008350#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008351 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008352#endif
8353#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008354 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008355#endif
8356#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008357 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008358#endif
8359#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008360 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008361#endif
8362#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008363 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008364#endif
8365#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008367#endif
8368#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008369 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008370#endif
8371#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008372 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008373#endif
Fred Draked86ed291999-12-15 15:34:33 +00008374#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008375 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008376#endif
Fred Drakec9680921999-12-13 16:37:25 +00008377#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008379#endif
Fred Draked86ed291999-12-15 15:34:33 +00008380#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008381 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008382#endif
8383#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008384 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008385#endif
8386#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008387 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008388#endif
8389#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008391#endif
Fred Drakec9680921999-12-13 16:37:25 +00008392#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008393 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008394#endif
8395#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008396 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008397#endif
8398#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008399 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008400#endif
8401#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008403#endif
8404#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008405 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008406#endif
8407#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008408 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008409#endif
8410#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008411 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008412#endif
8413#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008414 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008415#endif
8416#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008417 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008418#endif
8419#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008420 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008421#endif
8422#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008423 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008424#endif
8425#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008426 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008427#endif
8428#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008429 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008430#endif
8431#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008432 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008433#endif
8434#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008435 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008436#endif
8437#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008438 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008439#endif
Fred Draked86ed291999-12-15 15:34:33 +00008440#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008441 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008442#endif
8443#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008444 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008445#endif
8446#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008447 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008448#endif
8449#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008450 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008451#endif
8452#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008453 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008454#endif
8455#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008456 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008457#endif
8458#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008459 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008460#endif
8461#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008462 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008463#endif
8464#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008465 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008466#endif
8467#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008468 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008469#endif
8470#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008471 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008472#endif
8473#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008474 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008475#endif
8476#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008477 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008478#endif
Fred Drakec9680921999-12-13 16:37:25 +00008479};
8480
8481static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008482conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008483{
8484 return conv_confname(arg, valuep, posix_constants_confstr,
8485 sizeof(posix_constants_confstr)
8486 / sizeof(struct constdef));
8487}
8488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008489PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008490"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008491Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008492
8493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008494posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008495{
8496 PyObject *result = NULL;
8497 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008498 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008499 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008500
Victor Stinnercb043522010-09-10 23:49:04 +00008501 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8502 return NULL;
8503
8504 errno = 0;
8505 len = confstr(name, buffer, sizeof(buffer));
8506 if (len == 0) {
8507 if (errno) {
8508 posix_error();
8509 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008510 }
8511 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008512 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008513 }
8514 }
Victor Stinnercb043522010-09-10 23:49:04 +00008515
8516 if ((unsigned int)len >= sizeof(buffer)) {
8517 char *buf = PyMem_Malloc(len);
8518 if (buf == NULL)
8519 return PyErr_NoMemory();
8520 confstr(name, buf, len);
8521 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8522 PyMem_Free(buf);
8523 }
8524 else
8525 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008526 return result;
8527}
8528#endif
8529
8530
8531#ifdef HAVE_SYSCONF
8532static struct constdef posix_constants_sysconf[] = {
8533#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008534 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008535#endif
8536#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008537 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008538#endif
8539#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008540 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008541#endif
8542#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008543 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008544#endif
8545#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008546 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008547#endif
8548#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008549 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008550#endif
8551#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008552 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008553#endif
8554#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008555 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008556#endif
8557#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008558 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008559#endif
8560#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008561 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008562#endif
Fred Draked86ed291999-12-15 15:34:33 +00008563#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008564 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008565#endif
8566#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008567 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008568#endif
Fred Drakec9680921999-12-13 16:37:25 +00008569#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008570 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008571#endif
Fred Drakec9680921999-12-13 16:37:25 +00008572#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008573 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008574#endif
8575#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008576 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008577#endif
8578#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008580#endif
8581#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008582 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008583#endif
8584#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008585 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008586#endif
Fred Draked86ed291999-12-15 15:34:33 +00008587#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008588 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008589#endif
Fred Drakec9680921999-12-13 16:37:25 +00008590#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008591 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008592#endif
8593#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008594 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008595#endif
8596#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008597 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008598#endif
8599#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008600 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008601#endif
8602#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008603 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008604#endif
Fred Draked86ed291999-12-15 15:34:33 +00008605#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008606 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008607#endif
Fred Drakec9680921999-12-13 16:37:25 +00008608#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008609 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008610#endif
8611#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008612 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008613#endif
8614#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008615 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008616#endif
8617#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008618 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008619#endif
8620#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008621 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008622#endif
8623#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008624 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008625#endif
8626#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008627 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008628#endif
8629#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008630 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008631#endif
8632#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008633 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008634#endif
8635#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008636 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008637#endif
8638#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008639 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008640#endif
8641#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008642 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008643#endif
8644#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008645 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008646#endif
8647#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008648 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008649#endif
8650#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008651 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008652#endif
8653#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008654 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008655#endif
8656#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008657 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008658#endif
8659#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008660 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008661#endif
8662#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008663 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008664#endif
8665#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008666 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008667#endif
8668#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008669 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008670#endif
8671#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008672 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008673#endif
8674#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008675 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008676#endif
Fred Draked86ed291999-12-15 15:34:33 +00008677#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00008678 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008679#endif
Fred Drakec9680921999-12-13 16:37:25 +00008680#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008681 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008682#endif
8683#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008684 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008685#endif
8686#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008687 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008688#endif
Fred Draked86ed291999-12-15 15:34:33 +00008689#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008690 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008691#endif
Fred Drakec9680921999-12-13 16:37:25 +00008692#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00008693 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008694#endif
Fred Draked86ed291999-12-15 15:34:33 +00008695#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008696 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008697#endif
8698#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00008699 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008700#endif
Fred Drakec9680921999-12-13 16:37:25 +00008701#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008702 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008703#endif
8704#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008705 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008706#endif
8707#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008708 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008709#endif
8710#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008711 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008712#endif
Fred Draked86ed291999-12-15 15:34:33 +00008713#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00008714 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008715#endif
Fred Drakec9680921999-12-13 16:37:25 +00008716#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00008717 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008718#endif
8719#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00008720 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008721#endif
8722#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008723 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008724#endif
8725#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008726 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008727#endif
8728#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008729 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008730#endif
8731#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00008732 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008733#endif
8734#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00008735 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008736#endif
Fred Draked86ed291999-12-15 15:34:33 +00008737#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00008738 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008739#endif
Fred Drakec9680921999-12-13 16:37:25 +00008740#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008741 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008742#endif
8743#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008744 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008745#endif
Fred Draked86ed291999-12-15 15:34:33 +00008746#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008747 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008748#endif
Fred Drakec9680921999-12-13 16:37:25 +00008749#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008750 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008751#endif
8752#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008753 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008754#endif
8755#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008756 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008757#endif
8758#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008759 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008760#endif
8761#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008762 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008763#endif
8764#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008765 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008766#endif
8767#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008768 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008769#endif
8770#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008771 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008772#endif
8773#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008774 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008775#endif
Fred Draked86ed291999-12-15 15:34:33 +00008776#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008777 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008778#endif
8779#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008780 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008781#endif
Fred Drakec9680921999-12-13 16:37:25 +00008782#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00008783 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008784#endif
8785#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008786 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008787#endif
8788#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008789 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008790#endif
8791#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008792 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008793#endif
8794#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008795 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008796#endif
8797#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008798 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008799#endif
8800#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00008801 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008802#endif
8803#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00008804 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008805#endif
8806#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008807 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008808#endif
8809#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008810 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008811#endif
8812#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00008813 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008814#endif
8815#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008816 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008817#endif
8818#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008819 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008820#endif
8821#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00008822 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008823#endif
8824#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00008825 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008826#endif
8827#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00008828 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008829#endif
8830#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00008831 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008832#endif
8833#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008834 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008835#endif
8836#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008838#endif
8839#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008841#endif
8842#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008844#endif
8845#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008846 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008847#endif
8848#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00008849 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008850#endif
8851#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008853#endif
8854#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008856#endif
8857#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008859#endif
8860#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008862#endif
8863#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008865#endif
8866#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008867 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008868#endif
8869#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008870 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008871#endif
8872#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008874#endif
8875#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008876 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008877#endif
8878#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008879 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008880#endif
8881#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008882 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008883#endif
8884#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008885 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008886#endif
Fred Draked86ed291999-12-15 15:34:33 +00008887#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00008888 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008889#endif
Fred Drakec9680921999-12-13 16:37:25 +00008890#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00008891 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008892#endif
8893#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008894 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008895#endif
8896#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00008897 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008898#endif
8899#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008900 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008901#endif
8902#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008903 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008904#endif
8905#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00008906 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008907#endif
8908#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00008909 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008910#endif
8911#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008912 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008913#endif
8914#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008916#endif
8917#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008919#endif
8920#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008921 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008922#endif
8923#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008924 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008925#endif
8926#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008927 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008928#endif
8929#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00008930 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008931#endif
8932#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00008933 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008934#endif
8935#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008937#endif
8938#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008940#endif
8941#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008943#endif
8944#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008946#endif
8947#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008949#endif
8950#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008952#endif
8953#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008954 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008955#endif
8956#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008957 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008958#endif
8959#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008960 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008961#endif
8962#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00008963 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008964#endif
8965#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008966 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008967#endif
8968#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008969 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008970#endif
8971#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008972 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008973#endif
8974#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008975 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008976#endif
8977#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00008978 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008979#endif
8980#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008981 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008982#endif
8983#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00008984 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008985#endif
8986#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008987 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008988#endif
8989#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00008990 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008991#endif
8992#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00008993 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008994#endif
8995#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00008996 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008997#endif
8998#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008999 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009000#endif
9001#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009002 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009003#endif
9004#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009005 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009006#endif
9007#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009008 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009009#endif
9010#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009011 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009012#endif
9013#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009014 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009015#endif
9016#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009017 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009018#endif
9019#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009020 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009021#endif
9022#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009023 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009024#endif
9025};
9026
9027static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009028conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009029{
9030 return conv_confname(arg, valuep, posix_constants_sysconf,
9031 sizeof(posix_constants_sysconf)
9032 / sizeof(struct constdef));
9033}
9034
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009035PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009036"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009037Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009038
9039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009040posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009041{
9042 PyObject *result = NULL;
9043 int name;
9044
9045 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9046 int value;
9047
9048 errno = 0;
9049 value = sysconf(name);
9050 if (value == -1 && errno != 0)
9051 posix_error();
9052 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009053 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009054 }
9055 return result;
9056}
9057#endif
9058
9059
Fred Drakebec628d1999-12-15 18:31:10 +00009060/* This code is used to ensure that the tables of configuration value names
9061 * are in sorted order as required by conv_confname(), and also to build the
9062 * the exported dictionaries that are used to publish information about the
9063 * names available on the host platform.
9064 *
9065 * Sorting the table at runtime ensures that the table is properly ordered
9066 * when used, even for platforms we're not able to test on. It also makes
9067 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009068 */
Fred Drakebec628d1999-12-15 18:31:10 +00009069
9070static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009071cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009072{
9073 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009074 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009075 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009076 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009077
9078 return strcmp(c1->name, c2->name);
9079}
9080
9081static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009082setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009084{
Fred Drakebec628d1999-12-15 18:31:10 +00009085 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009086 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009087
9088 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9089 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009090 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009092
Barry Warsaw3155db32000-04-13 15:20:40 +00009093 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009094 PyObject *o = PyLong_FromLong(table[i].value);
9095 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9096 Py_XDECREF(o);
9097 Py_DECREF(d);
9098 return -1;
9099 }
9100 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009101 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009102 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009103}
9104
Fred Drakebec628d1999-12-15 18:31:10 +00009105/* Return -1 on failure, 0 on success. */
9106static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009107setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009108{
9109#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009110 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009111 sizeof(posix_constants_pathconf)
9112 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009113 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009114 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009115#endif
9116#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009117 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009118 sizeof(posix_constants_confstr)
9119 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009120 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009121 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009122#endif
9123#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009124 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009125 sizeof(posix_constants_sysconf)
9126 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009127 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009128 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009129#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009130 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009131}
Fred Draked86ed291999-12-15 15:34:33 +00009132
9133
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009134PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009135"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009136Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009137in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009138
9139static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009140posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009141{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009142 abort();
9143 /*NOTREACHED*/
9144 Py_FatalError("abort() called from Python code didn't abort!");
9145 return NULL;
9146}
Fred Drakebec628d1999-12-15 18:31:10 +00009147
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009148#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009149PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009150"startfile(filepath [, operation]) - Start a file with its associated\n\
9151application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009152\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009153When \"operation\" is not specified or \"open\", this acts like\n\
9154double-clicking the file in Explorer, or giving the file name as an\n\
9155argument to the DOS \"start\" command: the file is opened with whatever\n\
9156application (if any) its extension is associated.\n\
9157When another \"operation\" is given, it specifies what should be done with\n\
9158the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009159\n\
9160startfile returns as soon as the associated application is launched.\n\
9161There is no option to wait for the application to close, and no way\n\
9162to retrieve the application's exit status.\n\
9163\n\
9164The filepath is relative to the current directory. If you want to use\n\
9165an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009166the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009167
9168static PyObject *
9169win32_startfile(PyObject *self, PyObject *args)
9170{
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 PyObject *ofilepath;
9172 char *filepath;
9173 char *operation = NULL;
9174 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009175
Victor Stinner8c62be82010-05-06 00:08:46 +00009176 PyObject *unipath, *woperation = NULL;
9177 if (!PyArg_ParseTuple(args, "U|s:startfile",
9178 &unipath, &operation)) {
9179 PyErr_Clear();
9180 goto normal;
9181 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009182
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 if (operation) {
9184 woperation = PyUnicode_DecodeASCII(operation,
9185 strlen(operation), NULL);
9186 if (!woperation) {
9187 PyErr_Clear();
9188 operation = NULL;
9189 goto normal;
9190 }
9191 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009192
Victor Stinner8c62be82010-05-06 00:08:46 +00009193 Py_BEGIN_ALLOW_THREADS
9194 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
9195 PyUnicode_AS_UNICODE(unipath),
9196 NULL, NULL, SW_SHOWNORMAL);
9197 Py_END_ALLOW_THREADS
9198
9199 Py_XDECREF(woperation);
9200 if (rc <= (HINSTANCE)32) {
9201 PyObject *errval = win32_error_unicode("startfile",
9202 PyUnicode_AS_UNICODE(unipath));
9203 return errval;
9204 }
9205 Py_INCREF(Py_None);
9206 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009207
9208normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9210 PyUnicode_FSConverter, &ofilepath,
9211 &operation))
9212 return NULL;
9213 filepath = PyBytes_AsString(ofilepath);
9214 Py_BEGIN_ALLOW_THREADS
9215 rc = ShellExecute((HWND)0, operation, filepath,
9216 NULL, NULL, SW_SHOWNORMAL);
9217 Py_END_ALLOW_THREADS
9218 if (rc <= (HINSTANCE)32) {
9219 PyObject *errval = win32_error("startfile", filepath);
9220 Py_DECREF(ofilepath);
9221 return errval;
9222 }
9223 Py_DECREF(ofilepath);
9224 Py_INCREF(Py_None);
9225 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009226}
9227#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009228
Martin v. Löwis438b5342002-12-27 10:16:42 +00009229#ifdef HAVE_GETLOADAVG
9230PyDoc_STRVAR(posix_getloadavg__doc__,
9231"getloadavg() -> (float, float, float)\n\n\
9232Return the number of processes in the system run queue averaged over\n\
9233the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9234was unobtainable");
9235
9236static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009237posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009238{
9239 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009240 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009241 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9242 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009243 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009244 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009245}
9246#endif
9247
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009248#ifdef MS_WINDOWS
9249
9250PyDoc_STRVAR(win32_urandom__doc__,
9251"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009252Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009253
9254typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
9255 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
9256 DWORD dwFlags );
9257typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
9258 BYTE *pbBuffer );
9259
9260static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00009261/* This handle is never explicitly released. Instead, the operating
9262 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009263static HCRYPTPROV hCryptProv = 0;
9264
Tim Peters4ad82172004-08-30 17:02:04 +00009265static PyObject*
9266win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009267{
Victor Stinner8c62be82010-05-06 00:08:46 +00009268 int howMany;
9269 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009270
Victor Stinner8c62be82010-05-06 00:08:46 +00009271 /* Read arguments */
9272 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9273 return NULL;
9274 if (howMany < 0)
9275 return PyErr_Format(PyExc_ValueError,
9276 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009277
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 if (hCryptProv == 0) {
9279 HINSTANCE hAdvAPI32 = NULL;
9280 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009281
Victor Stinner8c62be82010-05-06 00:08:46 +00009282 /* Obtain handle to the DLL containing CryptoAPI
9283 This should not fail */
9284 hAdvAPI32 = GetModuleHandle("advapi32.dll");
9285 if(hAdvAPI32 == NULL)
9286 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009287
Victor Stinner8c62be82010-05-06 00:08:46 +00009288 /* Obtain pointers to the CryptoAPI functions
9289 This will fail on some early versions of Win95 */
9290 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
9291 hAdvAPI32,
9292 "CryptAcquireContextA");
9293 if (pCryptAcquireContext == NULL)
9294 return PyErr_Format(PyExc_NotImplementedError,
9295 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009296
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
9298 hAdvAPI32, "CryptGenRandom");
9299 if (pCryptGenRandom == NULL)
9300 return PyErr_Format(PyExc_NotImplementedError,
9301 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009302
Victor Stinner8c62be82010-05-06 00:08:46 +00009303 /* Acquire context */
9304 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
9305 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
9306 return win32_error("CryptAcquireContext", NULL);
9307 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009308
Victor Stinner8c62be82010-05-06 00:08:46 +00009309 /* Allocate bytes */
9310 result = PyBytes_FromStringAndSize(NULL, howMany);
9311 if (result != NULL) {
9312 /* Get random data */
9313 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
9314 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
9315 PyBytes_AS_STRING(result))) {
9316 Py_DECREF(result);
9317 return win32_error("CryptGenRandom", NULL);
9318 }
9319 }
9320 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009321}
9322#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009323
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009324PyDoc_STRVAR(device_encoding__doc__,
9325"device_encoding(fd) -> str\n\n\
9326Return a string describing the encoding of the device\n\
9327if the output is a terminal; else return None.");
9328
9329static PyObject *
9330device_encoding(PyObject *self, PyObject *args)
9331{
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 int fd;
Victor Stinner7870bdf2011-05-23 18:12:52 +02009333#if defined(MS_WINDOWS) || defined(MS_WIN64)
9334 UINT cp;
9335#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009336 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9337 return NULL;
9338 if (!_PyVerify_fd(fd) || !isatty(fd)) {
9339 Py_INCREF(Py_None);
9340 return Py_None;
9341 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009342#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner7870bdf2011-05-23 18:12:52 +02009343 if (fd == 0)
9344 cp = GetConsoleCP();
9345 else if (fd == 1 || fd == 2)
9346 cp = GetConsoleOutputCP();
9347 else
9348 cp = 0;
9349 /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
9350 has no console */
9351 if (cp != 0)
9352 return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009353#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00009354 {
9355 char *codeset = nl_langinfo(CODESET);
9356 if (codeset != NULL && codeset[0] != 0)
9357 return PyUnicode_FromString(codeset);
9358 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009359#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 Py_INCREF(Py_None);
9361 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009362}
9363
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009364#ifdef __VMS
9365/* Use openssl random routine */
9366#include <openssl/rand.h>
9367PyDoc_STRVAR(vms_urandom__doc__,
9368"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009369Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009370
9371static PyObject*
9372vms_urandom(PyObject *self, PyObject *args)
9373{
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 int howMany;
9375 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009376
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 /* Read arguments */
9378 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9379 return NULL;
9380 if (howMany < 0)
9381 return PyErr_Format(PyExc_ValueError,
9382 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009383
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 /* Allocate bytes */
9385 result = PyBytes_FromStringAndSize(NULL, howMany);
9386 if (result != NULL) {
9387 /* Get random data */
9388 if (RAND_pseudo_bytes((unsigned char*)
9389 PyBytes_AS_STRING(result),
9390 howMany) < 0) {
9391 Py_DECREF(result);
9392 return PyErr_Format(PyExc_ValueError,
9393 "RAND_pseudo_bytes");
9394 }
9395 }
9396 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009397}
9398#endif
9399
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009400#ifdef HAVE_SETRESUID
9401PyDoc_STRVAR(posix_setresuid__doc__,
9402"setresuid(ruid, euid, suid)\n\n\
9403Set the current process's real, effective, and saved user ids.");
9404
9405static PyObject*
9406posix_setresuid (PyObject *self, PyObject *args)
9407{
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 /* We assume uid_t is no larger than a long. */
9409 long ruid, euid, suid;
9410 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9411 return NULL;
9412 if (setresuid(ruid, euid, suid) < 0)
9413 return posix_error();
9414 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009415}
9416#endif
9417
9418#ifdef HAVE_SETRESGID
9419PyDoc_STRVAR(posix_setresgid__doc__,
9420"setresgid(rgid, egid, sgid)\n\n\
9421Set the current process's real, effective, and saved group ids.");
9422
9423static PyObject*
9424posix_setresgid (PyObject *self, PyObject *args)
9425{
Victor Stinner8c62be82010-05-06 00:08:46 +00009426 /* We assume uid_t is no larger than a long. */
9427 long rgid, egid, sgid;
9428 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9429 return NULL;
9430 if (setresgid(rgid, egid, sgid) < 0)
9431 return posix_error();
9432 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009433}
9434#endif
9435
9436#ifdef HAVE_GETRESUID
9437PyDoc_STRVAR(posix_getresuid__doc__,
9438"getresuid() -> (ruid, euid, suid)\n\n\
9439Get tuple of the current process's real, effective, and saved user ids.");
9440
9441static PyObject*
9442posix_getresuid (PyObject *self, PyObject *noargs)
9443{
Victor Stinner8c62be82010-05-06 00:08:46 +00009444 uid_t ruid, euid, suid;
9445 long l_ruid, l_euid, l_suid;
9446 if (getresuid(&ruid, &euid, &suid) < 0)
9447 return posix_error();
9448 /* Force the values into long's as we don't know the size of uid_t. */
9449 l_ruid = ruid;
9450 l_euid = euid;
9451 l_suid = suid;
9452 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009453}
9454#endif
9455
9456#ifdef HAVE_GETRESGID
9457PyDoc_STRVAR(posix_getresgid__doc__,
9458"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009459Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009460
9461static PyObject*
9462posix_getresgid (PyObject *self, PyObject *noargs)
9463{
Victor Stinner8c62be82010-05-06 00:08:46 +00009464 uid_t rgid, egid, sgid;
9465 long l_rgid, l_egid, l_sgid;
9466 if (getresgid(&rgid, &egid, &sgid) < 0)
9467 return posix_error();
9468 /* Force the values into long's as we don't know the size of uid_t. */
9469 l_rgid = rgid;
9470 l_egid = egid;
9471 l_sgid = sgid;
9472 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009473}
9474#endif
9475
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009476/* Posix *at family of functions:
9477 faccessat, fchmodat, fchownat, fstatat, futimesat,
9478 linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
9479 unlinkat, utimensat, mkfifoat */
9480
9481#ifdef HAVE_FACCESSAT
9482PyDoc_STRVAR(posix_faccessat__doc__,
9483"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
9484Like access() but if path is relative, it is taken as relative to dirfd.\n\
9485flags is optional and can be constructed by ORing together zero or more\n\
9486of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\n\
9487If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9488is interpreted relative to the current working directory.");
9489
9490static PyObject *
9491posix_faccessat(PyObject *self, PyObject *args)
9492{
9493 PyObject *opath;
9494 char *path;
9495 int mode;
9496 int res;
9497 int dirfd, flags = 0;
9498 if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
9499 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9500 return NULL;
9501 path = PyBytes_AsString(opath);
9502 Py_BEGIN_ALLOW_THREADS
9503 res = faccessat(dirfd, path, mode, flags);
9504 Py_END_ALLOW_THREADS
9505 Py_DECREF(opath);
9506 return PyBool_FromLong(res == 0);
9507}
9508#endif
9509
9510#ifdef HAVE_FCHMODAT
9511PyDoc_STRVAR(posix_fchmodat__doc__,
9512"fchmodat(dirfd, path, mode, flags=0)\n\n\
9513Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
9514flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9515If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9516is interpreted relative to the current working directory.");
9517
9518static PyObject *
9519posix_fchmodat(PyObject *self, PyObject *args)
9520{
9521 int dirfd, mode, res;
9522 int flags = 0;
9523 PyObject *opath;
9524 char *path;
9525
9526 if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
9527 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9528 return NULL;
9529
9530 path = PyBytes_AsString(opath);
9531
9532 Py_BEGIN_ALLOW_THREADS
9533 res = fchmodat(dirfd, path, mode, flags);
9534 Py_END_ALLOW_THREADS
9535 Py_DECREF(opath);
9536 if (res < 0)
9537 return posix_error();
9538 Py_RETURN_NONE;
9539}
9540#endif /* HAVE_FCHMODAT */
9541
9542#ifdef HAVE_FCHOWNAT
9543PyDoc_STRVAR(posix_fchownat__doc__,
9544"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
9545Like chown() but if path is relative, it is taken as relative to dirfd.\n\
9546flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9547If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9548is interpreted relative to the current working directory.");
9549
9550static PyObject *
9551posix_fchownat(PyObject *self, PyObject *args)
9552{
9553 PyObject *opath;
9554 int dirfd, res;
9555 long uid, gid;
9556 int flags = 0;
9557 char *path;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009558
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009559 if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
9560 &dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
9561 return NULL;
9562
9563 path = PyBytes_AsString(opath);
9564
9565 Py_BEGIN_ALLOW_THREADS
9566 res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
9567 Py_END_ALLOW_THREADS
9568 Py_DECREF(opath);
9569 if (res < 0)
9570 return posix_error();
9571 Py_RETURN_NONE;
9572}
9573#endif /* HAVE_FCHOWNAT */
9574
9575#ifdef HAVE_FSTATAT
9576PyDoc_STRVAR(posix_fstatat__doc__,
9577"fstatat(dirfd, path, flags=0) -> stat result\n\n\
9578Like stat() but if path is relative, it is taken as relative to dirfd.\n\
9579flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9580If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9581is interpreted relative to the current working directory.");
9582
9583static PyObject *
9584posix_fstatat(PyObject *self, PyObject *args)
9585{
9586 PyObject *opath;
9587 char *path;
9588 STRUCT_STAT st;
9589 int dirfd, res, flags = 0;
9590
9591 if (!PyArg_ParseTuple(args, "iO&|i:fstatat",
9592 &dirfd, PyUnicode_FSConverter, &opath, &flags))
9593 return NULL;
9594 path = PyBytes_AsString(opath);
9595
9596 Py_BEGIN_ALLOW_THREADS
9597 res = fstatat(dirfd, path, &st, flags);
9598 Py_END_ALLOW_THREADS
9599 Py_DECREF(opath);
9600 if (res != 0)
9601 return posix_error();
9602
9603 return _pystat_fromstructstat(&st);
9604}
9605#endif
9606
9607#ifdef HAVE_FUTIMESAT
9608PyDoc_STRVAR(posix_futimesat__doc__,
9609"futimesat(dirfd, path, (atime, mtime))\n\
9610futimesat(dirfd, path, None)\n\n\
9611Like utime() but if path is relative, it is taken as relative to dirfd.\n\
9612If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9613is interpreted relative to the current working directory.");
9614
9615static PyObject *
9616posix_futimesat(PyObject *self, PyObject *args)
9617{
9618 PyObject *opath;
9619 char *path;
9620 int res, dirfd;
9621 PyObject* arg;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009622 time_t atime, mtime;
9623 long ausec, musec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009624
9625 if (!PyArg_ParseTuple(args, "iO&O:futimesat",
9626 &dirfd, PyUnicode_FSConverter, &opath, &arg))
9627 return NULL;
9628 path = PyBytes_AsString(opath);
9629 if (arg == Py_None) {
9630 /* optional time values not given */
9631 Py_BEGIN_ALLOW_THREADS
9632 res = futimesat(dirfd, path, NULL);
9633 Py_END_ALLOW_THREADS
9634 }
9635 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
9636 PyErr_SetString(PyExc_TypeError,
9637 "futimesat() arg 3 must be a tuple (atime, mtime)");
9638 Py_DECREF(opath);
9639 return NULL;
9640 }
9641 else {
9642 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009643 &atime, &ausec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009644 Py_DECREF(opath);
9645 return NULL;
9646 }
9647 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009648 &mtime, &musec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009649 Py_DECREF(opath);
9650 return NULL;
9651 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009652
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009653 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009654 {
9655#ifdef HAVE_UTIMENSAT
9656 struct timespec buf[2];
9657 buf[0].tv_sec = atime;
9658 buf[0].tv_nsec = ausec;
9659 buf[1].tv_sec = mtime;
9660 buf[1].tv_nsec = musec;
9661 res = utimensat(dirfd, path, buf, 0);
9662#else
9663 struct timeval buf[2];
9664 buf[0].tv_sec = atime;
9665 buf[0].tv_usec = ausec;
9666 buf[1].tv_sec = mtime;
9667 buf[1].tv_usec = musec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009668 res = futimesat(dirfd, path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009669#endif
9670 }
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009671 Py_END_ALLOW_THREADS
9672 }
9673 Py_DECREF(opath);
9674 if (res < 0) {
9675 return posix_error();
9676 }
9677 Py_RETURN_NONE;
9678}
9679#endif
9680
9681#ifdef HAVE_LINKAT
9682PyDoc_STRVAR(posix_linkat__doc__,
9683"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
9684Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
9685and if dstpath is relative, it is taken as relative to dstfd.\n\
9686flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
9687If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
9688srcpath is interpreted relative to the current working directory. This\n\
9689also applies for dstpath.");
9690
9691static PyObject *
9692posix_linkat(PyObject *self, PyObject *args)
9693{
9694 PyObject *osrc, *odst;
9695 char *src, *dst;
9696 int res, srcfd, dstfd;
9697 int flags = 0;
9698
9699 if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
9700 &srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
9701 return NULL;
9702 src = PyBytes_AsString(osrc);
9703 dst = PyBytes_AsString(odst);
9704 Py_BEGIN_ALLOW_THREADS
9705 res = linkat(srcfd, src, dstfd, dst, flags);
9706 Py_END_ALLOW_THREADS
9707 Py_DECREF(osrc);
9708 Py_DECREF(odst);
9709 if (res < 0)
9710 return posix_error();
9711 Py_RETURN_NONE;
9712}
9713#endif /* HAVE_LINKAT */
9714
9715#ifdef HAVE_MKDIRAT
9716PyDoc_STRVAR(posix_mkdirat__doc__,
9717"mkdirat(dirfd, path, mode=0o777)\n\n\
9718Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
9719If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9720is interpreted relative to the current working directory.");
9721
9722static PyObject *
9723posix_mkdirat(PyObject *self, PyObject *args)
9724{
9725 int res, dirfd;
9726 PyObject *opath;
9727 char *path;
9728 int mode = 0777;
9729
9730 if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
9731 &dirfd, PyUnicode_FSConverter, &opath, &mode))
9732 return NULL;
9733 path = PyBytes_AsString(opath);
9734 Py_BEGIN_ALLOW_THREADS
9735 res = mkdirat(dirfd, path, mode);
9736 Py_END_ALLOW_THREADS
9737 Py_DECREF(opath);
9738 if (res < 0)
9739 return posix_error();
9740 Py_RETURN_NONE;
9741}
9742#endif
9743
9744#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
9745PyDoc_STRVAR(posix_mknodat__doc__,
9746"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
9747Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
9748If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9749is interpreted relative to the current working directory.");
9750
9751static PyObject *
9752posix_mknodat(PyObject *self, PyObject *args)
9753{
9754 PyObject *opath;
9755 char *filename;
9756 int mode = 0600;
9757 int device = 0;
9758 int res, dirfd;
9759 if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
9760 PyUnicode_FSConverter, &opath, &mode, &device))
9761 return NULL;
9762 filename = PyBytes_AS_STRING(opath);
9763 Py_BEGIN_ALLOW_THREADS
9764 res = mknodat(dirfd, filename, mode, device);
9765 Py_END_ALLOW_THREADS
9766 Py_DECREF(opath);
9767 if (res < 0)
9768 return posix_error();
9769 Py_RETURN_NONE;
9770}
9771#endif
9772
9773#ifdef HAVE_OPENAT
9774PyDoc_STRVAR(posix_openat__doc__,
9775"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
9776Like open() but if path is relative, it is taken as relative to dirfd.\n\
9777If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9778is interpreted relative to the current working directory.");
9779
9780static PyObject *
9781posix_openat(PyObject *self, PyObject *args)
9782{
9783 PyObject *ofile;
9784 char *file;
9785 int flag, dirfd, fd;
9786 int mode = 0777;
9787
9788 if (!PyArg_ParseTuple(args, "iO&i|i:openat",
9789 &dirfd, PyUnicode_FSConverter, &ofile,
9790 &flag, &mode))
9791 return NULL;
9792 file = PyBytes_AsString(ofile);
9793 Py_BEGIN_ALLOW_THREADS
9794 fd = openat(dirfd, file, flag, mode);
9795 Py_END_ALLOW_THREADS
9796 Py_DECREF(ofile);
9797 if (fd < 0)
9798 return posix_error();
9799 return PyLong_FromLong((long)fd);
9800}
9801#endif
9802
9803#ifdef HAVE_READLINKAT
9804PyDoc_STRVAR(posix_readlinkat__doc__,
9805"readlinkat(dirfd, path) -> path\n\n\
9806Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
9807If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9808is interpreted relative to the current working directory.");
9809
9810static PyObject *
9811posix_readlinkat(PyObject *self, PyObject *args)
9812{
9813 PyObject *v, *opath;
9814 char buf[MAXPATHLEN];
9815 char *path;
9816 int n, dirfd;
9817 int arg_is_unicode = 0;
9818
9819 if (!PyArg_ParseTuple(args, "iO&:readlinkat",
9820 &dirfd, PyUnicode_FSConverter, &opath))
9821 return NULL;
9822 path = PyBytes_AsString(opath);
9823 v = PySequence_GetItem(args, 1);
9824 if (v == NULL) {
9825 Py_DECREF(opath);
9826 return NULL;
9827 }
9828
9829 if (PyUnicode_Check(v)) {
9830 arg_is_unicode = 1;
9831 }
9832 Py_DECREF(v);
9833
9834 Py_BEGIN_ALLOW_THREADS
9835 n = readlinkat(dirfd, path, buf, (int) sizeof buf);
9836 Py_END_ALLOW_THREADS
9837 Py_DECREF(opath);
9838 if (n < 0)
9839 return posix_error();
9840
9841 if (arg_is_unicode)
9842 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
9843 else
9844 return PyBytes_FromStringAndSize(buf, n);
9845}
9846#endif /* HAVE_READLINKAT */
9847
9848#ifdef HAVE_RENAMEAT
9849PyDoc_STRVAR(posix_renameat__doc__,
9850"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
9851Like rename() but if oldpath is relative, it is taken as relative to\n\
9852olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
9853If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
9854oldpath is interpreted relative to the current working directory. This\n\
9855also applies for newpath.");
9856
9857static PyObject *
9858posix_renameat(PyObject *self, PyObject *args)
9859{
9860 int res;
9861 PyObject *opathold, *opathnew;
9862 char *opath, *npath;
9863 int oldfd, newfd;
9864
9865 if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
9866 &oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
9867 return NULL;
9868 opath = PyBytes_AsString(opathold);
9869 npath = PyBytes_AsString(opathnew);
9870 Py_BEGIN_ALLOW_THREADS
9871 res = renameat(oldfd, opath, newfd, npath);
9872 Py_END_ALLOW_THREADS
9873 Py_DECREF(opathold);
9874 Py_DECREF(opathnew);
9875 if (res < 0)
9876 return posix_error();
9877 Py_RETURN_NONE;
9878}
9879#endif
9880
9881#if HAVE_SYMLINKAT
9882PyDoc_STRVAR(posix_symlinkat__doc__,
9883"symlinkat(src, dstfd, dst)\n\n\
9884Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
9885If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
9886is interpreted relative to the current working directory.");
9887
9888static PyObject *
9889posix_symlinkat(PyObject *self, PyObject *args)
9890{
9891 int res, dstfd;
9892 PyObject *osrc, *odst;
9893 char *src, *dst;
9894
9895 if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
9896 PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
9897 return NULL;
9898 src = PyBytes_AsString(osrc);
9899 dst = PyBytes_AsString(odst);
9900 Py_BEGIN_ALLOW_THREADS
9901 res = symlinkat(src, dstfd, dst);
9902 Py_END_ALLOW_THREADS
9903 Py_DECREF(osrc);
9904 Py_DECREF(odst);
9905 if (res < 0)
9906 return posix_error();
9907 Py_RETURN_NONE;
9908}
9909#endif /* HAVE_SYMLINKAT */
9910
9911#ifdef HAVE_UNLINKAT
9912PyDoc_STRVAR(posix_unlinkat__doc__,
9913"unlinkat(dirfd, path, flags=0)\n\n\
9914Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
9915flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
9916specified, unlinkat() behaves like rmdir().\n\
9917If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9918is interpreted relative to the current working directory.");
9919
9920static PyObject *
9921posix_unlinkat(PyObject *self, PyObject *args)
9922{
9923 int dirfd, res, flags = 0;
9924 PyObject *opath;
9925 char *path;
9926
9927 if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
9928 &dirfd, PyUnicode_FSConverter, &opath, &flags))
9929 return NULL;
9930 path = PyBytes_AsString(opath);
9931 Py_BEGIN_ALLOW_THREADS
9932 res = unlinkat(dirfd, path, flags);
9933 Py_END_ALLOW_THREADS
9934 Py_DECREF(opath);
9935 if (res < 0)
9936 return posix_error();
9937 Py_RETURN_NONE;
9938}
9939#endif
9940
9941#ifdef HAVE_UTIMENSAT
9942PyDoc_STRVAR(posix_utimensat__doc__,
9943"utimensat(dirfd, path, (atime_sec, atime_nsec),\n\
9944 (mtime_sec, mtime_nsec), flags)\n\
9945utimensat(dirfd, path, None, None, flags)\n\n\
9946Updates the timestamps of a file with nanosecond precision. If path is\n\
9947relative, it is taken as relative to dirfd.\n\
9948The second form sets atime and mtime to the current time.\n\
9949flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9950If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9951is interpreted relative to the current working directory.\n\
9952If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
9953current time.\n\
9954If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
9955
9956static PyObject *
9957posix_utimensat(PyObject *self, PyObject *args)
9958{
9959 PyObject *opath;
9960 char *path;
9961 int res, dirfd, flags = 0;
9962 PyObject *atime, *mtime;
9963
9964 struct timespec buf[2];
9965
9966 if (!PyArg_ParseTuple(args, "iO&OO|i:utimensat",
9967 &dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
9968 return NULL;
9969 path = PyBytes_AsString(opath);
9970 if (atime == Py_None && mtime == Py_None) {
9971 /* optional time values not given */
9972 Py_BEGIN_ALLOW_THREADS
9973 res = utimensat(dirfd, path, NULL, flags);
9974 Py_END_ALLOW_THREADS
9975 }
9976 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
9977 PyErr_SetString(PyExc_TypeError,
9978 "utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
9979 Py_DECREF(opath);
9980 return NULL;
9981 }
9982 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
9983 PyErr_SetString(PyExc_TypeError,
9984 "utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
9985 Py_DECREF(opath);
9986 return NULL;
9987 }
9988 else {
9989 if (!PyArg_ParseTuple(atime, "ll:utimensat",
9990 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
9991 Py_DECREF(opath);
9992 return NULL;
9993 }
9994 if (!PyArg_ParseTuple(mtime, "ll:utimensat",
9995 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
9996 Py_DECREF(opath);
9997 return NULL;
9998 }
9999 Py_BEGIN_ALLOW_THREADS
10000 res = utimensat(dirfd, path, buf, flags);
10001 Py_END_ALLOW_THREADS
10002 }
10003 Py_DECREF(opath);
10004 if (res < 0) {
10005 return posix_error();
10006 }
10007 Py_RETURN_NONE;
10008}
10009#endif
10010
10011#ifdef HAVE_MKFIFOAT
10012PyDoc_STRVAR(posix_mkfifoat__doc__,
10013"mkfifoat(dirfd, path, mode=0o666)\n\n\
10014Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
10015If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10016is interpreted relative to the current working directory.");
10017
10018static PyObject *
10019posix_mkfifoat(PyObject *self, PyObject *args)
10020{
10021 PyObject *opath;
10022 char *filename;
10023 int mode = 0666;
10024 int res, dirfd;
10025 if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
10026 &dirfd, PyUnicode_FSConverter, &opath, &mode))
10027 return NULL;
10028 filename = PyBytes_AS_STRING(opath);
10029 Py_BEGIN_ALLOW_THREADS
10030 res = mkfifoat(dirfd, filename, mode);
10031 Py_END_ALLOW_THREADS
10032 Py_DECREF(opath);
10033 if (res < 0)
10034 return posix_error();
10035 Py_RETURN_NONE;
10036}
10037#endif
10038
Benjamin Peterson9428d532011-09-14 11:45:52 -040010039#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010040
10041static int
10042try_getxattr(const char *path, const char *name,
10043 ssize_t (*get)(const char *, const char *, void *, size_t),
10044 Py_ssize_t buf_size, PyObject **res)
10045{
10046 PyObject *value;
10047 Py_ssize_t len;
10048
10049 assert(buf_size <= XATTR_SIZE_MAX);
10050 value = PyBytes_FromStringAndSize(NULL, buf_size);
10051 if (!value)
10052 return 0;
10053 Py_BEGIN_ALLOW_THREADS;
10054 len = get(path, name, PyBytes_AS_STRING(value), buf_size);
10055 Py_END_ALLOW_THREADS;
10056 if (len < 0) {
10057 Py_DECREF(value);
10058 if (errno == ERANGE) {
10059 value = NULL;
10060 }
10061 else {
10062 posix_error();
10063 return 0;
10064 }
10065 }
10066 else if (len != buf_size) {
10067 /* Can only shrink. */
10068 _PyBytes_Resize(&value, len);
10069 }
10070 *res = value;
10071 return 1;
10072}
10073
10074static PyObject *
10075getxattr_common(const char *path, PyObject *name_obj,
10076 ssize_t (*get)(const char *, const char *, void *, size_t))
10077{
10078 PyObject *value;
10079 const char *name = PyBytes_AS_STRING(name_obj);
10080
10081 /* Try a small value first. */
10082 if (!try_getxattr(path, name, get, 128, &value))
10083 return NULL;
10084 if (value)
10085 return value;
10086 /* Now the maximum possible one. */
10087 if (!try_getxattr(path, name, get, XATTR_SIZE_MAX, &value))
10088 return NULL;
10089 assert(value);
10090 return value;
10091}
10092
10093PyDoc_STRVAR(posix_getxattr__doc__,
10094"getxattr(path, attr) -> value\n\n\
10095Return the value of extended attribute *name* on *path*.");
10096
10097static PyObject *
10098posix_getxattr(PyObject *self, PyObject *args)
10099{
10100 PyObject *path, *res, *name;
10101
10102 if (!PyArg_ParseTuple(args, "O&O&:getxattr", PyUnicode_FSConverter, &path,
10103 PyUnicode_FSConverter, &name))
10104 return NULL;
10105 res = getxattr_common(PyBytes_AS_STRING(path), name, getxattr);
10106 Py_DECREF(path);
10107 Py_DECREF(name);
10108 return res;
10109}
10110
10111PyDoc_STRVAR(posix_lgetxattr__doc__,
10112"lgetxattr(path, attr) -> value\n\n\
10113Like getxattr but don't follow symlinks.");
10114
10115static PyObject *
10116posix_lgetxattr(PyObject *self, PyObject *args)
10117{
10118 PyObject *path, *res, *name;
10119
10120 if (!PyArg_ParseTuple(args, "O&O&:lgetxattr", PyUnicode_FSConverter, &path,
10121 PyUnicode_FSConverter, &name))
10122 return NULL;
10123 res = getxattr_common(PyBytes_AS_STRING(path), name, lgetxattr);
10124 Py_DECREF(path);
10125 Py_DECREF(name);
10126 return res;
10127}
10128
10129static ssize_t
10130wrap_fgetxattr(const char *path, const char *name, void *value, size_t size)
10131{
10132 /* Hack to share code. */
10133 return fgetxattr((int)(Py_uintptr_t)path, name, value, size);
10134}
10135
10136PyDoc_STRVAR(posix_fgetxattr__doc__,
10137"fgetxattr(fd, attr) -> value\n\n\
10138Like getxattr but operate on a fd instead of a path.");
10139
10140static PyObject *
10141posix_fgetxattr(PyObject *self, PyObject *args)
10142{
10143 PyObject *res, *name;
10144 int fd;
10145
10146 if (!PyArg_ParseTuple(args, "iO&:fgetxattr", &fd, PyUnicode_FSConverter, &name))
10147 return NULL;
10148 res = getxattr_common((const char *)(Py_uintptr_t)fd, name, wrap_fgetxattr);
10149 Py_DECREF(name);
10150 return res;
10151}
10152
10153PyDoc_STRVAR(posix_setxattr__doc__,
10154"setxattr(path, attr, value, flags=0)\n\n\
10155Set extended attribute *attr* on *path* to *value*.");
10156
10157static PyObject *
10158posix_setxattr(PyObject *self, PyObject *args)
10159{
10160 PyObject *path, *name;
10161 Py_buffer data;
10162 int flags = 0, err;
10163
10164 if (!PyArg_ParseTuple(args, "O&O&y*|i:setxattr", PyUnicode_FSConverter,
10165 &path, PyUnicode_FSConverter, &name, &data, &flags))
10166 return NULL;
10167 Py_BEGIN_ALLOW_THREADS;
10168 err = setxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10169 data.buf, data.len, flags);
10170 Py_END_ALLOW_THREADS;
10171 Py_DECREF(path);
10172 Py_DECREF(name);
10173 PyBuffer_Release(&data);
10174 if (err)
10175 return posix_error();
10176 Py_RETURN_NONE;
10177}
10178
10179PyDoc_STRVAR(posix_lsetxattr__doc__,
10180"lsetxattr(path, attr, value, flags=0)\n\n\
10181Like setxattr but don't follow symlinks.");
10182
10183static PyObject *
10184posix_lsetxattr(PyObject *self, PyObject *args)
10185{
10186 PyObject *path, *name;
10187 Py_buffer data;
10188 int flags = 0, err;
10189
10190 if (!PyArg_ParseTuple(args, "O&O&y*|i:lsetxattr", PyUnicode_FSConverter,
10191 &path, PyUnicode_FSConverter, &name, &data, &flags))
10192 return NULL;
10193 Py_BEGIN_ALLOW_THREADS;
10194 err = lsetxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10195 data.buf, data.len, flags);
10196 Py_END_ALLOW_THREADS;
10197 Py_DECREF(path);
10198 Py_DECREF(name);
10199 PyBuffer_Release(&data);
10200 if (err)
10201 return posix_error();
10202 Py_RETURN_NONE;
10203}
10204
10205PyDoc_STRVAR(posix_fsetxattr__doc__,
10206"fsetxattr(fd, attr, value, flags=0)\n\n\
10207Like setxattr but operates on *fd* instead of a path.");
10208
10209static PyObject *
10210posix_fsetxattr(PyObject *self, PyObject *args)
10211{
10212 Py_buffer data;
10213 const char *name;
10214 int fd, flags = 0, err;
10215
10216 if (!PyArg_ParseTuple(args, "iO&y*|i:fsetxattr", &fd, PyUnicode_FSConverter,
10217 &name, &data, &flags))
10218 return NULL;
10219 Py_BEGIN_ALLOW_THREADS;
10220 err = fsetxattr(fd, PyBytes_AS_STRING(name), data.buf, data.len, flags);
10221 Py_END_ALLOW_THREADS;
10222 Py_DECREF(name);
10223 PyBuffer_Release(&data);
10224 if (err)
10225 return posix_error();
10226 Py_RETURN_NONE;
10227}
10228
10229PyDoc_STRVAR(posix_removexattr__doc__,
10230"removexattr(path, attr)\n\n\
10231Remove extended attribute *attr* on *path*.");
10232
10233static PyObject *
10234posix_removexattr(PyObject *self, PyObject *args)
10235{
10236 PyObject *path, *name;
10237 int err;
10238
10239 if (!PyArg_ParseTuple(args, "O&O&:removexattr", PyUnicode_FSConverter, &path,
10240 PyUnicode_FSConverter, &name))
10241 return NULL;
10242 Py_BEGIN_ALLOW_THREADS;
10243 err = removexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10244 Py_END_ALLOW_THREADS;
10245 Py_DECREF(path);
10246 Py_DECREF(name);
10247 if (err)
10248 return posix_error();
10249 Py_RETURN_NONE;
10250}
10251
10252PyDoc_STRVAR(posix_lremovexattr__doc__,
10253"lremovexattr(path, attr)\n\n\
10254Like removexattr but don't follow symlinks.");
10255
10256static PyObject *
10257posix_lremovexattr(PyObject *self, PyObject *args)
10258{
10259 PyObject *path, *name;
10260 int err;
10261
10262 if (!PyArg_ParseTuple(args, "O&O&:lremovexattr", PyUnicode_FSConverter, &path,
10263 PyUnicode_FSConverter, &name))
10264 return NULL;
10265 Py_BEGIN_ALLOW_THREADS;
10266 err = lremovexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10267 Py_END_ALLOW_THREADS;
10268 Py_DECREF(path);
10269 Py_DECREF(name);
10270 if (err)
10271 return posix_error();
10272 Py_RETURN_NONE;
10273}
10274
10275PyDoc_STRVAR(posix_fremovexattr__doc__,
10276"fremovexattr(fd, attr)\n\n\
10277Like removexattr but operates on a file descriptor.");
10278
10279static PyObject *
10280posix_fremovexattr(PyObject *self, PyObject *args)
10281{
10282 PyObject *name;
10283 int fd, err;
10284
10285 if (!PyArg_ParseTuple(args, "iO&:fremovexattr", &fd,
10286 PyUnicode_FSConverter, &name))
10287 return NULL;
10288 Py_BEGIN_ALLOW_THREADS;
10289 err = fremovexattr(fd, PyBytes_AS_STRING(name));
10290 Py_END_ALLOW_THREADS;
10291 Py_DECREF(name);
10292 if (err)
10293 return posix_error();
10294 Py_RETURN_NONE;
10295}
10296
10297static Py_ssize_t
10298try_listxattr(const char *path, ssize_t (*list)(const char *, char *, size_t),
10299 Py_ssize_t buf_size, char **buf)
10300{
10301 Py_ssize_t len;
10302
10303 *buf = PyMem_MALLOC(buf_size);
10304 if (!*buf) {
10305 PyErr_NoMemory();
10306 return -1;
10307 }
10308 Py_BEGIN_ALLOW_THREADS;
10309 len = list(path, *buf, buf_size);
10310 Py_END_ALLOW_THREADS;
10311 if (len < 0) {
10312 PyMem_FREE(*buf);
10313 if (errno != ERANGE)
10314 posix_error();
10315 return -1;
10316 }
10317 return len;
10318}
10319
10320static PyObject *
10321listxattr_common(const char *path, ssize_t (*list)(const char *, char *, size_t))
10322{
10323 PyObject *res, *attr;
10324 Py_ssize_t len, err, start, i;
10325 char *buf;
10326
10327 len = try_listxattr(path, list, 256, &buf);
10328 if (len < 0) {
10329 if (PyErr_Occurred())
10330 return NULL;
10331 len = try_listxattr(path, list, XATTR_LIST_MAX, &buf);
10332 if (len < 0)
10333 return NULL;
10334 }
10335 res = PyList_New(0);
10336 if (!res) {
10337 PyMem_FREE(buf);
10338 return NULL;
10339 }
10340 for (start = i = 0; i < len; i++) {
10341 if (!buf[i]) {
10342 attr = PyUnicode_DecodeFSDefaultAndSize(&buf[start], i - start);
10343 if (!attr) {
10344 Py_DECREF(res);
10345 PyMem_FREE(buf);
10346 return NULL;
10347 }
10348 err = PyList_Append(res, attr);
10349 Py_DECREF(attr);
10350 if (err) {
10351 Py_DECREF(res);
10352 PyMem_FREE(buf);
10353 return NULL;
10354 }
10355 start = i + 1;
10356 }
10357 }
10358 PyMem_FREE(buf);
10359 return res;
10360}
10361
10362PyDoc_STRVAR(posix_listxattr__doc__,
10363"listxattr(path)\n\n\
10364Return a list of extended attributes on *path*.");
10365
10366static PyObject *
10367posix_listxattr(PyObject *self, PyObject *args)
10368{
10369 PyObject *path, *res;
10370
10371 if (!PyArg_ParseTuple(args, "O&:listxattr", PyUnicode_FSConverter, &path))
10372 return NULL;
10373 res = listxattr_common(PyBytes_AS_STRING(path), listxattr);
10374 Py_DECREF(path);
10375 return res;
10376}
10377
10378PyDoc_STRVAR(posix_llistxattr__doc__,
10379"llistxattr(path)\n\n\
10380Like listxattr but don't follow symlinks..");
10381
10382static PyObject *
10383posix_llistxattr(PyObject *self, PyObject *args)
10384{
10385 PyObject *path, *res;
10386
10387 if (!PyArg_ParseTuple(args, "O&:llistxattr", PyUnicode_FSConverter, &path))
10388 return NULL;
10389 res = listxattr_common(PyBytes_AS_STRING(path), llistxattr);
10390 Py_DECREF(path);
10391 return res;
10392}
10393
10394static ssize_t
10395wrap_flistxattr(const char *path, char *buf, size_t len)
10396{
10397 /* Hack to share code. */
10398 return flistxattr((int)(Py_uintptr_t)path, buf, len);
10399}
10400
10401PyDoc_STRVAR(posix_flistxattr__doc__,
10402"flistxattr(path)\n\n\
10403Like flistxattr but operates on a file descriptor.");
10404
10405static PyObject *
10406posix_flistxattr(PyObject *self, PyObject *args)
10407{
10408 long fd;
10409
10410 if (!PyArg_ParseTuple(args, "i:flistxattr", &fd))
10411 return NULL;
10412 return listxattr_common((const char *)(Py_uintptr_t)fd, wrap_flistxattr);
10413}
10414
Benjamin Peterson9428d532011-09-14 11:45:52 -040010415#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010416
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010417static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010419#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010421#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010423#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010425#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +000010426 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010427#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010428 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010429#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010430#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010432#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010433#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010435#endif /* HAVE_LCHMOD */
10436#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010438#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010439#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010441#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010442#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010444#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010445#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010447#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010448#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010450#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +000010451#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10453 METH_NOARGS, posix_getcwd__doc__},
10454 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10455 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +000010456#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010457#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010459#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010461#ifdef HAVE_FDOPENDIR
10462 {"fdlistdir", posix_fdlistdir, METH_VARARGS, posix_fdlistdir__doc__},
10463#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
10465 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010466#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010468#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010469#ifdef HAVE_GETPRIORITY
10470 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10471#endif /* HAVE_GETPRIORITY */
10472#ifdef HAVE_SETPRIORITY
10473 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10474#endif /* HAVE_SETPRIORITY */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010475#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010476 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010477#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010478#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010479 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010480#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010481 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
10482 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
10483 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +000010485#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010487#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +000010488#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010489 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +000010490 win_symlink__doc__},
10491#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010492#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010494#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010495 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010496#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010498#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +000010499 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
10500 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
10501 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010502#ifdef HAVE_FUTIMES
10503 {"futimes", posix_futimes, METH_VARARGS, posix_futimes__doc__},
10504#endif
10505#ifdef HAVE_LUTIMES
10506 {"lutimes", posix_lutimes, METH_VARARGS, posix_lutimes__doc__},
10507#endif
10508#ifdef HAVE_FUTIMENS
10509 {"futimens", posix_futimens, METH_VARARGS, posix_futimens__doc__},
10510#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010511#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010513#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010514 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010515#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
10517 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010518#endif /* HAVE_EXECV */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010519#ifdef HAVE_FEXECVE
10520 {"fexecve", posix_fexecve, METH_VARARGS, posix_fexecve__doc__},
10521#endif
Guido van Rossuma1065681999-01-25 23:20:23 +000010522#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10524 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010525#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10527 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010528#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010529#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010530#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010531 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010532#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010533#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010534 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010535#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010536#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010537#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010538 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10539 {"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 +020010540#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010541#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010542 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010543#endif
10544#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010545 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010546#endif
10547#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010548 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010549#endif
10550#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010551 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010552#endif
10553#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010554 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010555#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010556 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010557#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010558 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10559 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10560#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010561#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010562#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010564#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010565#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010567#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010568#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010570#endif /* HAVE_GETEGID */
10571#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010573#endif /* HAVE_GETEUID */
10574#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010576#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010577#ifdef HAVE_GETGROUPLIST
10578 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10579#endif
Fred Drakec9680921999-12-13 16:37:25 +000010580#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010582#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010584#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010585 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010586#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010587#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010589#endif /* HAVE_GETPPID */
10590#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010591 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010592#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010593#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010594 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010595#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010596#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010598#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010599#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010601#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010602#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010604#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010605#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010606 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10607 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +000010608 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010609#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010610#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010611 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010612#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010613#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010614 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010615#endif /* HAVE_SETEUID */
10616#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010618#endif /* HAVE_SETEGID */
10619#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010620 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010621#endif /* HAVE_SETREUID */
10622#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010624#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010625#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010626 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010627#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010628#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010629 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010630#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010631#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010632 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010633#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010634#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010635 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010636#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010637#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010638 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010639#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010640#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010641 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010642#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010643#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010645#endif /* HAVE_WAIT3 */
10646#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +000010647 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010648#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010649#if defined(HAVE_WAITID) && !defined(__APPLE__)
10650 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10651#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010652#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010653 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010654#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010655#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010657#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010658#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010659 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010660#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010661#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010663#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010664#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010665 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010666#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010667#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010668 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010669#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 {"open", posix_open, METH_VARARGS, posix_open__doc__},
10671 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10672 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10673 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10674 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10675 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010676#ifdef HAVE_LOCKF
10677 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10678#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10680 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010681#ifdef HAVE_READV
10682 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10683#endif
10684#ifdef HAVE_PREAD
10685 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10686#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010688#ifdef HAVE_WRITEV
10689 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10690#endif
10691#ifdef HAVE_PWRITE
10692 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10693#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010694#ifdef HAVE_SENDFILE
10695 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10696 posix_sendfile__doc__},
10697#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010698 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
10699 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010700#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010701 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010702#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010703#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010704 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010705#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010706#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +000010707 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010708#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010709#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +000010710 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010711#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010712#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010713 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10714 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10715 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010716#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010717#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010719#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010720#ifdef HAVE_TRUNCATE
10721 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
10722#endif
10723#ifdef HAVE_POSIX_FALLOCATE
10724 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10725#endif
10726#ifdef HAVE_POSIX_FADVISE
10727 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10728#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010729#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010730 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010731#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010732#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010734#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010736#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010737 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010738#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010739#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010740 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010741#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010742#ifdef HAVE_SYNC
10743 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10744#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010745#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010747#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010748#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010749#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010751#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010752#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010754#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010755#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010757#endif /* WIFSTOPPED */
10758#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010759 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010760#endif /* WIFSIGNALED */
10761#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010763#endif /* WIFEXITED */
10764#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010766#endif /* WEXITSTATUS */
10767#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010768 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010769#endif /* WTERMSIG */
10770#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010772#endif /* WSTOPSIG */
10773#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010774#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010776#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010777#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010779#endif
Fred Drakec9680921999-12-13 16:37:25 +000010780#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010782#endif
10783#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010785#endif
10786#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010788#endif
10789#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010791#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010792 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010793#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010794 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010795 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010796 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010797 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010798 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010799#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010800#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010801 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010802#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010803 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010804 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010805 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010806 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +000010807 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010808 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010809#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010810 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010811#endif
10812#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010813 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010814#endif
10815#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010816 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010817#endif
10818#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010819 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010820#endif
10821
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010822/* posix *at family of functions */
10823#ifdef HAVE_FACCESSAT
10824 {"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
10825#endif
10826#ifdef HAVE_FCHMODAT
10827 {"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
10828#endif /* HAVE_FCHMODAT */
10829#ifdef HAVE_FCHOWNAT
10830 {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
10831#endif /* HAVE_FCHOWNAT */
10832#ifdef HAVE_FSTATAT
10833 {"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__},
10834#endif
10835#ifdef HAVE_FUTIMESAT
10836 {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
10837#endif
10838#ifdef HAVE_LINKAT
10839 {"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
10840#endif /* HAVE_LINKAT */
10841#ifdef HAVE_MKDIRAT
10842 {"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
10843#endif
10844#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
10845 {"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
10846#endif
10847#ifdef HAVE_OPENAT
10848 {"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
10849#endif
10850#ifdef HAVE_READLINKAT
10851 {"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
10852#endif /* HAVE_READLINKAT */
10853#ifdef HAVE_RENAMEAT
10854 {"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
10855#endif
10856#if HAVE_SYMLINKAT
10857 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
10858#endif /* HAVE_SYMLINKAT */
10859#ifdef HAVE_UNLINKAT
10860 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
10861#endif
10862#ifdef HAVE_UTIMENSAT
10863 {"utimensat", posix_utimensat, METH_VARARGS, posix_utimensat__doc__},
10864#endif
10865#ifdef HAVE_MKFIFOAT
10866 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
10867#endif
Benjamin Peterson9428d532011-09-14 11:45:52 -040010868#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010869 {"setxattr", posix_setxattr, METH_VARARGS, posix_setxattr__doc__},
10870 {"lsetxattr", posix_lsetxattr, METH_VARARGS, posix_lsetxattr__doc__},
10871 {"fsetxattr", posix_fsetxattr, METH_VARARGS, posix_fsetxattr__doc__},
10872 {"getxattr", posix_getxattr, METH_VARARGS, posix_getxattr__doc__},
10873 {"lgetxattr", posix_lgetxattr, METH_VARARGS, posix_lgetxattr__doc__},
10874 {"fgetxattr", posix_fgetxattr, METH_VARARGS, posix_fgetxattr__doc__},
10875 {"removexattr", posix_removexattr, METH_VARARGS, posix_removexattr__doc__},
10876 {"lremovexattr", posix_lremovexattr, METH_VARARGS, posix_lremovexattr__doc__},
10877 {"fremovexattr", posix_fremovexattr, METH_VARARGS, posix_fremovexattr__doc__},
10878 {"listxattr", posix_listxattr, METH_VARARGS, posix_listxattr__doc__},
10879 {"llistxattr", posix_llistxattr, METH_VARARGS, posix_llistxattr__doc__},
10880 {"flistxattr", posix_flistxattr, METH_VARARGS, posix_flistxattr__doc__},
10881#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010883};
10884
10885
Barry Warsaw4a342091996-12-19 23:50:02 +000010886static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010887ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010888{
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010890}
10891
Guido van Rossumd48f2521997-12-05 22:19:34 +000010892#if defined(PYOS_OS2)
10893/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000010894static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000010895{
10896 APIRET rc;
10897 ULONG values[QSV_MAX+1];
10898 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000010899 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000010900
10901 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000010902 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000010903 Py_END_ALLOW_THREADS
10904
10905 if (rc != NO_ERROR) {
10906 os2_error(rc);
10907 return -1;
10908 }
10909
Fred Drake4d1e64b2002-04-15 19:40:07 +000010910 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
10911 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
10912 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
10913 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
10914 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
10915 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
10916 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000010917
10918 switch (values[QSV_VERSION_MINOR]) {
10919 case 0: ver = "2.00"; break;
10920 case 10: ver = "2.10"; break;
10921 case 11: ver = "2.11"; break;
10922 case 30: ver = "3.00"; break;
10923 case 40: ver = "4.00"; break;
10924 case 50: ver = "5.00"; break;
10925 default:
Tim Peters885d4572001-11-28 20:27:42 +000010926 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000010928 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000010929 ver = &tmp[0];
10930 }
10931
10932 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000010933 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000010934 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000010935
10936 /* Add Indicator of Which Drive was Used to Boot the System */
10937 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
10938 tmp[1] = ':';
10939 tmp[2] = '\0';
10940
Fred Drake4d1e64b2002-04-15 19:40:07 +000010941 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000010942}
10943#endif
10944
Brian Curtin52173d42010-12-02 18:29:18 +000010945#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010946static int
Brian Curtin52173d42010-12-02 18:29:18 +000010947enable_symlink()
10948{
10949 HANDLE tok;
10950 TOKEN_PRIVILEGES tok_priv;
10951 LUID luid;
10952 int meth_idx = 0;
10953
10954 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010955 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010956
10957 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010958 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010959
10960 tok_priv.PrivilegeCount = 1;
10961 tok_priv.Privileges[0].Luid = luid;
10962 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
10963
10964 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
10965 sizeof(TOKEN_PRIVILEGES),
10966 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010967 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010968
Brian Curtin3b4499c2010-12-28 14:31:47 +000010969 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
10970 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000010971}
10972#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
10973
Barry Warsaw4a342091996-12-19 23:50:02 +000010974static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000010975all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000010976{
Guido van Rossum94f6f721999-01-06 18:42:14 +000010977#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010979#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010980#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010981 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010982#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010983#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010984 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010985#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010986#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010988#endif
Fred Drakec9680921999-12-13 16:37:25 +000010989#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000010991#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010992#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010993 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010994#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010995#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010996 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010997#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010998#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000010999 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011000#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011001#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011002 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011003#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011004#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011005 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011006#endif
11007#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011009#endif
11010#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011012#endif
11013#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011014 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011015#endif
11016#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011018#endif
11019#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011021#endif
11022#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011023 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011024#endif
11025#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011027#endif
11028#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011030#endif
11031#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011033#endif
11034#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011036#endif
11037#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011039#endif
11040#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011042#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011043#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011045#endif
11046#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011048#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011049#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011051#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011052#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011054#endif
11055#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011057#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011058#ifdef PRIO_PROCESS
11059 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11060#endif
11061#ifdef PRIO_PGRP
11062 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11063#endif
11064#ifdef PRIO_USER
11065 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11066#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011067#ifdef O_CLOEXEC
11068 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11069#endif
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011070/* posix - constants for *at functions */
11071#ifdef AT_SYMLINK_NOFOLLOW
11072 if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
11073#endif
11074#ifdef AT_EACCESS
11075 if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
11076#endif
11077#ifdef AT_FDCWD
11078 if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
11079#endif
11080#ifdef AT_REMOVEDIR
11081 if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
11082#endif
11083#ifdef AT_SYMLINK_FOLLOW
11084 if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
11085#endif
11086#ifdef UTIME_NOW
11087 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11088#endif
11089#ifdef UTIME_OMIT
11090 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11091#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011092
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011093
Tim Peters5aa91602002-01-30 05:46:57 +000011094/* MS Windows */
11095#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011096 /* Don't inherit in child processes. */
11097 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011098#endif
11099#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 /* Optimize for short life (keep in memory). */
11101 /* MS forgot to define this one with a non-underscore form too. */
11102 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011103#endif
11104#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011105 /* Automatically delete when last handle is closed. */
11106 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011107#endif
11108#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 /* Optimize for random access. */
11110 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011111#endif
11112#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 /* Optimize for sequential access. */
11114 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011115#endif
11116
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011117/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011118#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 /* Send a SIGIO signal whenever input or output
11120 becomes available on file descriptor */
11121 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011122#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011123#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 /* Direct disk access. */
11125 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011126#endif
11127#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 /* Must be a directory. */
11129 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011130#endif
11131#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 /* Do not follow links. */
11133 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011134#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011135#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 /* Do not update the access time. */
11137 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011138#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011139
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011141#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011143#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011144#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011145 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011146#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011147#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011149#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011150#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011152#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011153#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011155#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011156#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011158#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011159#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011161#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011162#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011164#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011165#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011167#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011168#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011170#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011171#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011173#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011174#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011176#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011177#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011178 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011179#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011180#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011181 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011182#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011183#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011184 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011185#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011186#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011188#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011189#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011191#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011192
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011193 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011194#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011195 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011196#endif /* ST_RDONLY */
11197#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011198 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011199#endif /* ST_NOSUID */
11200
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011201 /* FreeBSD sendfile() constants */
11202#ifdef SF_NODISKIO
11203 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11204#endif
11205#ifdef SF_MNOWAIT
11206 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11207#endif
11208#ifdef SF_SYNC
11209 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11210#endif
11211
Ross Lagerwall7807c352011-03-17 20:20:30 +020011212 /* constants for posix_fadvise */
11213#ifdef POSIX_FADV_NORMAL
11214 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11215#endif
11216#ifdef POSIX_FADV_SEQUENTIAL
11217 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11218#endif
11219#ifdef POSIX_FADV_RANDOM
11220 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11221#endif
11222#ifdef POSIX_FADV_NOREUSE
11223 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11224#endif
11225#ifdef POSIX_FADV_WILLNEED
11226 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11227#endif
11228#ifdef POSIX_FADV_DONTNEED
11229 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11230#endif
11231
11232 /* constants for waitid */
11233#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11234 if (ins(d, "P_PID", (long)P_PID)) return -1;
11235 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11236 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11237#endif
11238#ifdef WEXITED
11239 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11240#endif
11241#ifdef WNOWAIT
11242 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11243#endif
11244#ifdef WSTOPPED
11245 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11246#endif
11247#ifdef CLD_EXITED
11248 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11249#endif
11250#ifdef CLD_DUMPED
11251 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11252#endif
11253#ifdef CLD_TRAPPED
11254 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11255#endif
11256#ifdef CLD_CONTINUED
11257 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11258#endif
11259
11260 /* constants for lockf */
11261#ifdef F_LOCK
11262 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11263#endif
11264#ifdef F_TLOCK
11265 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11266#endif
11267#ifdef F_ULOCK
11268 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11269#endif
11270#ifdef F_TEST
11271 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11272#endif
11273
11274 /* constants for futimens */
11275#ifdef UTIME_NOW
11276 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11277#endif
11278#ifdef UTIME_OMIT
11279 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11280#endif
11281
Guido van Rossum246bc171999-02-01 23:54:31 +000011282#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011283#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011284 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11285 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11286 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11287 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11288 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11289 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11290 if (ins(d, "P_PM", (long)P_PM)) return -1;
11291 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11292 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11293 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11294 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11295 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11296 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11297 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11298 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11299 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11300 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11301 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11302 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11303 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011304#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11306 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11307 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11308 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11309 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011310#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011311#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011312
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011313#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011314 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011315 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11316 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11317#ifdef SCHED_SPORADIC
11318 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11319#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011320#ifdef SCHED_BATCH
11321 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11322#endif
11323#ifdef SCHED_IDLE
11324 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11325#endif
11326#ifdef SCHED_RESET_ON_FORK
11327 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11328#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011329#ifdef SCHED_SYS
11330 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11331#endif
11332#ifdef SCHED_IA
11333 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11334#endif
11335#ifdef SCHED_FSS
11336 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11337#endif
11338#ifdef SCHED_FX
11339 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11340#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011341#endif
11342
Benjamin Peterson9428d532011-09-14 11:45:52 -040011343#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011344 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11345 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11346 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11347#endif
11348
Guido van Rossumd48f2521997-12-05 22:19:34 +000011349#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011350 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011351#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011352 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011353}
11354
11355
Tim Peters5aa91602002-01-30 05:46:57 +000011356#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011357#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011358#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011359
11360#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011361#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011362#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011363
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011364#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011365#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011366#define MODNAME "posix"
11367#endif
11368
Martin v. Löwis1a214512008-06-11 05:26:20 +000011369static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 PyModuleDef_HEAD_INIT,
11371 MODNAME,
11372 posix__doc__,
11373 -1,
11374 posix_methods,
11375 NULL,
11376 NULL,
11377 NULL,
11378 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011379};
11380
11381
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011382PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011383INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011384{
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +000011386
Brian Curtin52173d42010-12-02 18:29:18 +000011387#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011388 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011389#endif
11390
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 m = PyModule_Create(&posixmodule);
11392 if (m == NULL)
11393 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011394
Victor Stinner8c62be82010-05-06 00:08:46 +000011395 /* Initialize environ dictionary */
11396 v = convertenviron();
11397 Py_XINCREF(v);
11398 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11399 return NULL;
11400 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011401
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 if (all_ins(m))
11403 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011404
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 if (setup_confname_tables(m))
11406 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011407
Victor Stinner8c62be82010-05-06 00:08:46 +000011408 Py_INCREF(PyExc_OSError);
11409 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011410
Benjamin Peterson2740af82011-08-02 17:41:34 -050011411#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011412 if (PyType_Ready(&cpu_set_type) < 0)
11413 return NULL;
11414 Py_INCREF(&cpu_set_type);
11415 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011416#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011417
Guido van Rossumb3d39562000-01-31 18:41:26 +000011418#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011419 if (posix_putenv_garbage == NULL)
11420 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011421#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011422
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011424#if defined(HAVE_WAITID) && !defined(__APPLE__)
11425 waitid_result_desc.name = MODNAME ".waitid_result";
11426 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11427#endif
11428
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 stat_result_desc.name = MODNAME ".stat_result";
11430 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11431 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11432 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11433 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11434 structseq_new = StatResultType.tp_new;
11435 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011436
Victor Stinner8c62be82010-05-06 00:08:46 +000011437 statvfs_result_desc.name = MODNAME ".statvfs_result";
11438 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011439#ifdef NEED_TICKS_PER_SECOND
11440# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011442# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011443 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011444# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011445 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011446# endif
11447#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011448
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011449#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011450 sched_param_desc.name = MODNAME ".sched_param";
11451 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11452 SchedParamType.tp_new = sched_param_new;
11453#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011455#if defined(HAVE_WAITID) && !defined(__APPLE__)
11456 Py_INCREF((PyObject*) &WaitidResultType);
11457 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11458#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011459 Py_INCREF((PyObject*) &StatResultType);
11460 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11461 Py_INCREF((PyObject*) &StatVFSResultType);
11462 PyModule_AddObject(m, "statvfs_result",
11463 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011464
11465#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011466 Py_INCREF(&SchedParamType);
11467 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011468#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011469 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011470
11471#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 /*
11473 * Step 2 of weak-linking support on Mac OS X.
11474 *
11475 * The code below removes functions that are not available on the
11476 * currently active platform.
11477 *
11478 * This block allow one to use a python binary that was build on
11479 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
11480 * OSX 10.4.
11481 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011482#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 if (fstatvfs == NULL) {
11484 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11485 return NULL;
11486 }
11487 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011488#endif /* HAVE_FSTATVFS */
11489
11490#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011491 if (statvfs == NULL) {
11492 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11493 return NULL;
11494 }
11495 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011496#endif /* HAVE_STATVFS */
11497
11498# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011499 if (lchown == NULL) {
11500 if (PyObject_DelAttrString(m, "lchown") == -1) {
11501 return NULL;
11502 }
11503 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011504#endif /* HAVE_LCHOWN */
11505
11506
11507#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011509
Guido van Rossumb6775db1994-08-01 11:34:53 +000011510}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011511
11512#ifdef __cplusplus
11513}
11514#endif