blob: 40645ea71aa0e4dee0627c7fd0060c7518a7ed28 [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 Peterson2dbda072012-03-16 10:12:55 -0500110#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500111#undef HAVE_SCHED_SETAFFINITY
112#endif
113
Benjamin Peterson9428d532011-09-14 11:45:52 -0400114#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
115#define USE_XATTRS
116#endif
117
118#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400119#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400120#endif
121
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
123#ifdef HAVE_SYS_SOCKET_H
124#include <sys/socket.h>
125#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000126#endif
127
Victor Stinner8b905bd2011-10-25 13:34:04 +0200128#ifdef HAVE_DLFCN_H
129#include <dlfcn.h>
130#endif
131
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100132#if defined(MS_WINDOWS)
133# define TERMSIZE_USE_CONIO
134#elif defined(HAVE_SYS_IOCTL_H)
135# include <sys/ioctl.h>
136# if defined(HAVE_TERMIOS_H)
137# include <termios.h>
138# endif
139# if defined(TIOCGWINSZ)
140# define TERMSIZE_USE_IOCTL
141# endif
142#endif /* MS_WINDOWS */
143
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000145/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_GETCWD 1
151#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#if defined(__OS2__)
154#define HAVE_EXECV 1
155#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000156#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#include <process.h>
158#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_EXECV 1
161#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_OPENDIR 1
163#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_WAIT 1
166#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000168#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000169#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000170#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_EXECV 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
175#define HAVE_CWAIT 1
176#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000177#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000178#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000179#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
180/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182/* Unix functions that the configure script doesn't check for */
183#define HAVE_EXECV 1
184#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000186#define HAVE_FORK1 1
187#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_GETCWD 1
189#define HAVE_GETEGID 1
190#define HAVE_GETEUID 1
191#define HAVE_GETGID 1
192#define HAVE_GETPPID 1
193#define HAVE_GETUID 1
194#define HAVE_KILL 1
195#define HAVE_OPENDIR 1
196#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000197#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000199#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000200#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif /* _MSC_VER */
202#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000205
Victor Stinnera2f7c002012-02-08 03:36:25 +0100206
207
208
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000211#if defined(__sgi)&&_COMPILER_VERSION>=700
212/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
213 (default) */
214extern char *ctermid_r(char *);
215#endif
216
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000217#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000220#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000221#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
227#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000228extern int chdir(char *);
229extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000230#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chdir(const char *);
232extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000233#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000234#ifdef __BORLANDC__
235extern int chmod(const char *, int);
236#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000238#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000239/*#ifdef HAVE_FCHMOD
240extern int fchmod(int, mode_t);
241#endif*/
242/*#ifdef HAVE_LCHMOD
243extern int lchmod(const char *, mode_t);
244#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int chown(const char *, uid_t, gid_t);
246extern char *getcwd(char *, int);
247extern char *strerror(int);
248extern int link(const char *, const char *);
249extern int rename(const char *, const char *);
250extern int stat(const char *, struct stat *);
251extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000253extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000254#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000256extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000259
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000260#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#ifdef HAVE_UTIME_H
263#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000266#ifdef HAVE_SYS_UTIME_H
267#include <sys/utime.h>
268#define HAVE_UTIME_H /* pretend we do for the rest of this file */
269#endif /* HAVE_SYS_UTIME_H */
270
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#ifdef HAVE_SYS_TIMES_H
272#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274
275#ifdef HAVE_SYS_PARAM_H
276#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000277#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
279#ifdef HAVE_SYS_UTSNAME_H
280#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000281#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#define NAMLEN(dirent) strlen((dirent)->d_name)
286#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000287#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#include <direct.h>
289#define NAMLEN(dirent) strlen((dirent)->d_name)
290#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000292#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000293#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000294#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000296#endif
297#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000299#endif
300#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000302#endif
303#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000306#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000308#endif
309#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000311#endif
312#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000315#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000316#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000317#endif
318#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000319#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000320#endif
321#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000322#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000323#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000325#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000327#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000328#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000329#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
330#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000331static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000332#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000333#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000334
Guido van Rossumd48f2521997-12-05 22:19:34 +0000335#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000336#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000337#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Tim Petersbc2e10e2002-03-03 23:17:02 +0000339#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340#if defined(PATH_MAX) && PATH_MAX > 1024
341#define MAXPATHLEN PATH_MAX
342#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000343#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000344#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000345#endif /* MAXPATHLEN */
346
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000347#ifdef UNION_WAIT
348/* Emulate some macros on systems that have a union instead of macros */
349
350#ifndef WIFEXITED
351#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
352#endif
353
354#ifndef WEXITSTATUS
355#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
356#endif
357
358#ifndef WTERMSIG
359#define WTERMSIG(u_wait) ((u_wait).w_termsig)
360#endif
361
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000362#define WAIT_TYPE union wait
363#define WAIT_STATUS_INT(s) (s.w_status)
364
365#else /* !UNION_WAIT */
366#define WAIT_TYPE int
367#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000368#endif /* UNION_WAIT */
369
Greg Wardb48bc172000-03-01 21:51:56 +0000370/* Don't use the "_r" form if we don't need it (also, won't have a
371 prototype for it, at least on Solaris -- maybe others as well?). */
372#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
373#define USE_CTERMID_R
374#endif
375
Fred Drake699f3522000-06-29 21:12:41 +0000376/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000377#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000378#undef FSTAT
379#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000380#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000381# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700382# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000383# define FSTAT win32_fstat
384# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000385#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000386# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700387# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000388# define FSTAT fstat
389# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000390#endif
391
Tim Peters11b23062003-04-23 02:39:17 +0000392#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000393#include <sys/mkdev.h>
394#else
395#if defined(MAJOR_IN_SYSMACROS)
396#include <sys/sysmacros.h>
397#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000398#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
399#include <sys/mkdev.h>
400#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000401#endif
Fred Drake699f3522000-06-29 21:12:41 +0000402
Larry Hastings9cf065c2012-06-22 16:30:09 -0700403
404#ifdef MS_WINDOWS
405static int
406win32_warn_bytes_api()
407{
408 return PyErr_WarnEx(PyExc_DeprecationWarning,
409 "The Windows bytes API has been deprecated, "
410 "use Unicode filenames instead",
411 1);
412}
413#endif
414
415
416#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400417/*
418 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
419 * without the int cast, the value gets interpreted as uint (4291925331),
420 * which doesn't play nicely with all the initializer lines in this file that
421 * look like this:
422 * int dir_fd = DEFAULT_DIR_FD;
423 */
424#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700425#else
426#define DEFAULT_DIR_FD (-100)
427#endif
428
429static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200430_fd_converter(PyObject *o, int *p, const char *allowed)
431{
432 int overflow;
433 long long_value = PyLong_AsLongAndOverflow(o, &overflow);
434 if (PyFloat_Check(o) ||
435 (long_value == -1 && !overflow && PyErr_Occurred())) {
436 PyErr_Clear();
437 PyErr_Format(PyExc_TypeError,
438 "argument should be %s, not %.200s",
439 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700440 return 0;
441 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200442 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700443 PyErr_SetString(PyExc_OverflowError,
444 "signed integer is greater than maximum");
445 return 0;
446 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200447 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700448 PyErr_SetString(PyExc_OverflowError,
449 "signed integer is less than minimum");
450 return 0;
451 }
452 *p = (int)long_value;
453 return 1;
454}
455
456static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200457dir_fd_converter(PyObject *o, void *p)
458{
459 if (o == Py_None) {
460 *(int *)p = DEFAULT_DIR_FD;
461 return 1;
462 }
463 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700464}
465
466
467
468/*
469 * A PyArg_ParseTuple "converter" function
470 * that handles filesystem paths in the manner
471 * preferred by the os module.
472 *
473 * path_converter accepts (Unicode) strings and their
474 * subclasses, and bytes and their subclasses. What
475 * it does with the argument depends on the platform:
476 *
477 * * On Windows, if we get a (Unicode) string we
478 * extract the wchar_t * and return it; if we get
479 * bytes we extract the char * and return that.
480 *
481 * * On all other platforms, strings are encoded
482 * to bytes using PyUnicode_FSConverter, then we
483 * extract the char * from the bytes object and
484 * return that.
485 *
486 * path_converter also optionally accepts signed
487 * integers (representing open file descriptors) instead
488 * of path strings.
489 *
490 * Input fields:
491 * path.nullable
492 * If nonzero, the path is permitted to be None.
493 * path.allow_fd
494 * If nonzero, the path is permitted to be a file handle
495 * (a signed int) instead of a string.
496 * path.function_name
497 * If non-NULL, path_converter will use that as the name
498 * of the function in error messages.
499 * (If path.argument_name is NULL it omits the function name.)
500 * path.argument_name
501 * If non-NULL, path_converter will use that as the name
502 * of the parameter in error messages.
503 * (If path.argument_name is NULL it uses "path".)
504 *
505 * Output fields:
506 * path.wide
507 * Points to the path if it was expressed as Unicode
508 * and was not encoded. (Only used on Windows.)
509 * path.narrow
510 * Points to the path if it was expressed as bytes,
511 * or it was Unicode and was encoded to bytes.
512 * path.fd
513 * Contains a file descriptor if path.accept_fd was true
514 * and the caller provided a signed integer instead of any
515 * sort of string.
516 *
517 * WARNING: if your "path" parameter is optional, and is
518 * unspecified, path_converter will never get called.
519 * So if you set allow_fd, you *MUST* initialize path.fd = -1
520 * yourself!
521 * path.length
522 * The length of the path in characters, if specified as
523 * a string.
524 * path.object
525 * The original object passed in.
526 * path.cleanup
527 * For internal use only. May point to a temporary object.
528 * (Pay no attention to the man behind the curtain.)
529 *
530 * At most one of path.wide or path.narrow will be non-NULL.
531 * If path was None and path.nullable was set,
532 * or if path was an integer and path.allow_fd was set,
533 * both path.wide and path.narrow will be NULL
534 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200535 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700536 * path_converter takes care to not write to the path_t
537 * unless it's successful. However it must reset the
538 * "cleanup" field each time it's called.
539 *
540 * Use as follows:
541 * path_t path;
542 * memset(&path, 0, sizeof(path));
543 * PyArg_ParseTuple(args, "O&", path_converter, &path);
544 * // ... use values from path ...
545 * path_cleanup(&path);
546 *
547 * (Note that if PyArg_Parse fails you don't need to call
548 * path_cleanup(). However it is safe to do so.)
549 */
550typedef struct {
551 char *function_name;
552 char *argument_name;
553 int nullable;
554 int allow_fd;
555 wchar_t *wide;
556 char *narrow;
557 int fd;
558 Py_ssize_t length;
559 PyObject *object;
560 PyObject *cleanup;
561} path_t;
562
563static void
564path_cleanup(path_t *path) {
565 if (path->cleanup) {
566 Py_DECREF(path->cleanup);
567 path->cleanup = NULL;
568 }
569}
570
571static int
572path_converter(PyObject *o, void *p) {
573 path_t *path = (path_t *)p;
574 PyObject *unicode, *bytes;
575 Py_ssize_t length;
576 char *narrow;
577
578#define FORMAT_EXCEPTION(exc, fmt) \
579 PyErr_Format(exc, "%s%s" fmt, \
580 path->function_name ? path->function_name : "", \
581 path->function_name ? ": " : "", \
582 path->argument_name ? path->argument_name : "path")
583
584 /* Py_CLEANUP_SUPPORTED support */
585 if (o == NULL) {
586 path_cleanup(path);
587 return 1;
588 }
589
590 /* ensure it's always safe to call path_cleanup() */
591 path->cleanup = NULL;
592
593 if (o == Py_None) {
594 if (!path->nullable) {
595 FORMAT_EXCEPTION(PyExc_TypeError,
596 "can't specify None for %s argument");
597 return 0;
598 }
599 path->wide = NULL;
600 path->narrow = NULL;
601 path->length = 0;
602 path->object = o;
603 path->fd = -1;
604 return 1;
605 }
606
607 unicode = PyUnicode_FromObject(o);
608 if (unicode) {
609#ifdef MS_WINDOWS
610 wchar_t *wide;
611 length = PyUnicode_GET_SIZE(unicode);
612 if (length > 32767) {
613 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
614 Py_DECREF(unicode);
615 return 0;
616 }
617
618 wide = PyUnicode_AsUnicode(unicode);
619 if (!wide) {
620 Py_DECREF(unicode);
621 return 0;
622 }
623
624 path->wide = wide;
625 path->narrow = NULL;
626 path->length = length;
627 path->object = o;
628 path->fd = -1;
629 path->cleanup = unicode;
630 return Py_CLEANUP_SUPPORTED;
631#else
632 int converted = PyUnicode_FSConverter(unicode, &bytes);
633 Py_DECREF(unicode);
634 if (!converted)
635 bytes = NULL;
636#endif
637 }
638 else {
639 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200640 if (PyObject_CheckBuffer(o))
641 bytes = PyBytes_FromObject(o);
642 else
643 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700644 if (!bytes) {
645 PyErr_Clear();
646 if (path->allow_fd) {
647 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200648 int result = _fd_converter(o, &fd,
649 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700650 if (result) {
651 path->wide = NULL;
652 path->narrow = NULL;
653 path->length = 0;
654 path->object = o;
655 path->fd = fd;
656 return result;
657 }
658 }
659 }
660 }
661
662 if (!bytes) {
663 if (!PyErr_Occurred())
664 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
665 return 0;
666 }
667
668#ifdef MS_WINDOWS
669 if (win32_warn_bytes_api()) {
670 Py_DECREF(bytes);
671 return 0;
672 }
673#endif
674
675 length = PyBytes_GET_SIZE(bytes);
676#ifdef MS_WINDOWS
677 if (length > MAX_PATH) {
678 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
679 Py_DECREF(bytes);
680 return 0;
681 }
682#endif
683
684 narrow = PyBytes_AS_STRING(bytes);
685 if (length != strlen(narrow)) {
686 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
687 Py_DECREF(bytes);
688 return 0;
689 }
690
691 path->wide = NULL;
692 path->narrow = narrow;
693 path->length = length;
694 path->object = o;
695 path->fd = -1;
696 path->cleanup = bytes;
697 return Py_CLEANUP_SUPPORTED;
698}
699
700static void
701argument_unavailable_error(char *function_name, char *argument_name) {
702 PyErr_Format(PyExc_NotImplementedError,
703 "%s%s%s unavailable on this platform",
704 (function_name != NULL) ? function_name : "",
705 (function_name != NULL) ? ": ": "",
706 argument_name);
707}
708
709static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200710dir_fd_unavailable(PyObject *o, void *p)
711{
712 int dir_fd;
713 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700714 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200715 if (dir_fd != DEFAULT_DIR_FD) {
716 argument_unavailable_error(NULL, "dir_fd");
717 return 0;
718 }
719 *(int *)p = dir_fd;
720 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700721}
722
723static int
724fd_specified(char *function_name, int fd) {
725 if (fd == -1)
726 return 0;
727
728 argument_unavailable_error(function_name, "fd");
729 return 1;
730}
731
732static int
733follow_symlinks_specified(char *function_name, int follow_symlinks) {
734 if (follow_symlinks)
735 return 0;
736
737 argument_unavailable_error(function_name, "follow_symlinks");
738 return 1;
739}
740
741static int
742path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
743 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
744 PyErr_Format(PyExc_ValueError,
745 "%s: can't specify dir_fd without matching path",
746 function_name);
747 return 1;
748 }
749 return 0;
750}
751
752static int
753dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
754 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
755 PyErr_Format(PyExc_ValueError,
756 "%s: can't specify both dir_fd and fd",
757 function_name);
758 return 1;
759 }
760 return 0;
761}
762
763static int
764fd_and_follow_symlinks_invalid(char *function_name, int fd,
765 int follow_symlinks) {
766 if ((fd > 0) && (!follow_symlinks)) {
767 PyErr_Format(PyExc_ValueError,
768 "%s: cannot use fd and follow_symlinks together",
769 function_name);
770 return 1;
771 }
772 return 0;
773}
774
775static int
776dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
777 int follow_symlinks) {
778 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
779 PyErr_Format(PyExc_ValueError,
780 "%s: cannot use dir_fd and follow_symlinks together",
781 function_name);
782 return 1;
783 }
784 return 0;
785}
786
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200787/* A helper used by a number of POSIX-only functions */
788#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000789static int
790_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000791{
792#if !defined(HAVE_LARGEFILE_SUPPORT)
793 *((off_t*)addr) = PyLong_AsLong(arg);
794#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000795 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000796#endif
797 if (PyErr_Occurred())
798 return 0;
799 return 1;
800}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200801#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000802
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000803#if defined _MSC_VER && _MSC_VER >= 1400
804/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200805 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000806 * Normally, an invalid fd is likely to be a C program error and therefore
807 * an assertion can be useful, but it does contradict the POSIX standard
808 * which for write(2) states:
809 * "Otherwise, -1 shall be returned and errno set to indicate the error."
810 * "[EBADF] The fildes argument is not a valid file descriptor open for
811 * writing."
812 * Furthermore, python allows the user to enter any old integer
813 * as a fd and should merely raise a python exception on error.
814 * The Microsoft CRT doesn't provide an official way to check for the
815 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000816 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000817 * internal structures involved.
818 * The structures below must be updated for each version of visual studio
819 * according to the file internal.h in the CRT source, until MS comes
820 * up with a less hacky way to do this.
821 * (all of this is to avoid globally modifying the CRT behaviour using
822 * _set_invalid_parameter_handler() and _CrtSetReportMode())
823 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000824/* The actual size of the structure is determined at runtime.
825 * Only the first items must be present.
826 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000827typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000828 intptr_t osfhnd;
829 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000830} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000831
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000832extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000833#define IOINFO_L2E 5
834#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
835#define IOINFO_ARRAYS 64
836#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
837#define FOPEN 0x01
838#define _NO_CONSOLE_FILENO (intptr_t)-2
839
840/* This function emulates what the windows CRT does to validate file handles */
841int
842_PyVerify_fd(int fd)
843{
Victor Stinner8c62be82010-05-06 00:08:46 +0000844 const int i1 = fd >> IOINFO_L2E;
845 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000846
Antoine Pitrou22e41552010-08-15 18:07:50 +0000847 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000848
Victor Stinner8c62be82010-05-06 00:08:46 +0000849 /* Determine the actual size of the ioinfo structure,
850 * as used by the CRT loaded in memory
851 */
852 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
853 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
854 }
855 if (sizeof_ioinfo == 0) {
856 /* This should not happen... */
857 goto fail;
858 }
859
860 /* See that it isn't a special CLEAR fileno */
861 if (fd != _NO_CONSOLE_FILENO) {
862 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
863 * we check pointer validity and other info
864 */
865 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
866 /* finally, check that the file is open */
867 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
868 if (info->osfile & FOPEN) {
869 return 1;
870 }
871 }
872 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000873 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000874 errno = EBADF;
875 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000876}
877
878/* the special case of checking dup2. The target fd must be in a sensible range */
879static int
880_PyVerify_fd_dup2(int fd1, int fd2)
881{
Victor Stinner8c62be82010-05-06 00:08:46 +0000882 if (!_PyVerify_fd(fd1))
883 return 0;
884 if (fd2 == _NO_CONSOLE_FILENO)
885 return 0;
886 if ((unsigned)fd2 < _NHANDLE_)
887 return 1;
888 else
889 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000890}
891#else
892/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
893#define _PyVerify_fd_dup2(A, B) (1)
894#endif
895
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000896#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000897/* The following structure was copied from
898 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
899 include doesn't seem to be present in the Windows SDK (at least as included
900 with Visual Studio Express). */
901typedef struct _REPARSE_DATA_BUFFER {
902 ULONG ReparseTag;
903 USHORT ReparseDataLength;
904 USHORT Reserved;
905 union {
906 struct {
907 USHORT SubstituteNameOffset;
908 USHORT SubstituteNameLength;
909 USHORT PrintNameOffset;
910 USHORT PrintNameLength;
911 ULONG Flags;
912 WCHAR PathBuffer[1];
913 } SymbolicLinkReparseBuffer;
914
915 struct {
916 USHORT SubstituteNameOffset;
917 USHORT SubstituteNameLength;
918 USHORT PrintNameOffset;
919 USHORT PrintNameLength;
920 WCHAR PathBuffer[1];
921 } MountPointReparseBuffer;
922
923 struct {
924 UCHAR DataBuffer[1];
925 } GenericReparseBuffer;
926 };
927} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
928
929#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
930 GenericReparseBuffer)
931#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
932
933static int
Brian Curtind25aef52011-06-13 15:16:04 -0500934win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000935{
936 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
937 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
938 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000939
940 if (0 == DeviceIoControl(
941 reparse_point_handle,
942 FSCTL_GET_REPARSE_POINT,
943 NULL, 0, /* in buffer */
944 target_buffer, sizeof(target_buffer),
945 &n_bytes_returned,
946 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500947 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000948
949 if (reparse_tag)
950 *reparse_tag = rdb->ReparseTag;
951
Brian Curtind25aef52011-06-13 15:16:04 -0500952 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000953}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100954
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000955#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000956
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000957/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +0100958#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +0000959/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +0100960** environ directly, we must obtain it with _NSGetEnviron(). See also
961** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +0000962*/
963#include <crt_externs.h>
964static char **environ;
965#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000966extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000967#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000968
Barry Warsaw53699e91996-12-10 23:23:01 +0000969static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000970convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000971{
Victor Stinner8c62be82010-05-06 00:08:46 +0000972 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000973#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000974 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000975#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000976 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000977#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000978#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000979 APIRET rc;
980 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
981#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000982
Victor Stinner8c62be82010-05-06 00:08:46 +0000983 d = PyDict_New();
984 if (d == NULL)
985 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +0100986#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +0000987 if (environ == NULL)
988 environ = *_NSGetEnviron();
989#endif
990#ifdef MS_WINDOWS
991 /* _wenviron must be initialized in this way if the program is started
992 through main() instead of wmain(). */
993 _wgetenv(L"");
994 if (_wenviron == NULL)
995 return d;
996 /* This part ignores errors */
997 for (e = _wenviron; *e != NULL; e++) {
998 PyObject *k;
999 PyObject *v;
1000 wchar_t *p = wcschr(*e, L'=');
1001 if (p == NULL)
1002 continue;
1003 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1004 if (k == NULL) {
1005 PyErr_Clear();
1006 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001007 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001008 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1009 if (v == NULL) {
1010 PyErr_Clear();
1011 Py_DECREF(k);
1012 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001013 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001014 if (PyDict_GetItem(d, k) == NULL) {
1015 if (PyDict_SetItem(d, k, v) != 0)
1016 PyErr_Clear();
1017 }
1018 Py_DECREF(k);
1019 Py_DECREF(v);
1020 }
1021#else
1022 if (environ == NULL)
1023 return d;
1024 /* This part ignores errors */
1025 for (e = environ; *e != NULL; e++) {
1026 PyObject *k;
1027 PyObject *v;
1028 char *p = strchr(*e, '=');
1029 if (p == NULL)
1030 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001031 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001032 if (k == NULL) {
1033 PyErr_Clear();
1034 continue;
1035 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001036 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001037 if (v == NULL) {
1038 PyErr_Clear();
1039 Py_DECREF(k);
1040 continue;
1041 }
1042 if (PyDict_GetItem(d, k) == NULL) {
1043 if (PyDict_SetItem(d, k, v) != 0)
1044 PyErr_Clear();
1045 }
1046 Py_DECREF(k);
1047 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001048 }
1049#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001050#if defined(PYOS_OS2)
1051 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1052 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1053 PyObject *v = PyBytes_FromString(buffer);
1054 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1055 Py_DECREF(v);
1056 }
1057 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1058 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1059 PyObject *v = PyBytes_FromString(buffer);
1060 PyDict_SetItemString(d, "ENDLIBPATH", v);
1061 Py_DECREF(v);
1062 }
1063#endif
1064 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001065}
1066
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001067/* Set a POSIX-specific error from errno, and return NULL */
1068
Barry Warsawd58d7641998-07-23 16:14:40 +00001069static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001070posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001071{
Victor Stinner8c62be82010-05-06 00:08:46 +00001072 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001073}
Barry Warsawd58d7641998-07-23 16:14:40 +00001074static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001075posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001076{
Victor Stinner8c62be82010-05-06 00:08:46 +00001077 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001078}
1079
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001080
Mark Hammondef8b6542001-05-13 08:04:26 +00001081static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001082posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001083{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001084 PyObject *name_str, *rc;
1085 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1086 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001087 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001088 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1089 name_str);
1090 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001091 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001092}
1093
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001094#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001095static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001096win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001097{
Victor Stinner8c62be82010-05-06 00:08:46 +00001098 /* XXX We should pass the function name along in the future.
1099 (winreg.c also wants to pass the function name.)
1100 This would however require an additional param to the
1101 Windows error object, which is non-trivial.
1102 */
1103 errno = GetLastError();
1104 if (filename)
1105 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1106 else
1107 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001108}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001109
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001110static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001111win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001112{
Victor Stinner8c62be82010-05-06 00:08:46 +00001113 /* XXX - see win32_error for comments on 'function' */
1114 errno = GetLastError();
1115 if (filename)
1116 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1117 else
1118 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001119}
1120
Victor Stinnereb5657a2011-09-30 01:44:27 +02001121static PyObject *
1122win32_error_object(char* function, PyObject* filename)
1123{
1124 /* XXX - see win32_error for comments on 'function' */
1125 errno = GetLastError();
1126 if (filename)
1127 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1128 PyExc_WindowsError,
1129 errno,
1130 filename);
1131 else
1132 return PyErr_SetFromWindowsErr(errno);
1133}
1134
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001135#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001136
Larry Hastings9cf065c2012-06-22 16:30:09 -07001137/*
1138 * Some functions return Win32 errors, others only ever use posix_error
1139 * (this is for backwards compatibility with exceptions)
1140 */
1141static PyObject *
1142path_posix_error(char *function_name, path_t *path)
1143{
1144 if (path->narrow)
1145 return posix_error_with_filename(path->narrow);
1146 return posix_error();
1147}
1148
1149static PyObject *
1150path_error(char *function_name, path_t *path)
1151{
1152#ifdef MS_WINDOWS
1153 if (path->narrow)
1154 return win32_error(function_name, path->narrow);
1155 if (path->wide)
1156 return win32_error_unicode(function_name, path->wide);
1157 return win32_error(function_name, NULL);
1158#else
1159 return path_posix_error(function_name, path);
1160#endif
1161}
1162
Guido van Rossumd48f2521997-12-05 22:19:34 +00001163#if defined(PYOS_OS2)
1164/**********************************************************************
1165 * Helper Function to Trim and Format OS/2 Messages
1166 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001167static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001168os2_formatmsg(char *msgbuf, int msglen, char *reason)
1169{
1170 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1171
1172 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1173 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1174
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001175 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001176 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1177 }
1178
1179 /* Add Optional Reason Text */
1180 if (reason) {
1181 strcat(msgbuf, " : ");
1182 strcat(msgbuf, reason);
1183 }
1184}
1185
1186/**********************************************************************
1187 * Decode an OS/2 Operating System Error Code
1188 *
1189 * A convenience function to lookup an OS/2 error code and return a
1190 * text message we can use to raise a Python exception.
1191 *
1192 * Notes:
1193 * The messages for errors returned from the OS/2 kernel reside in
1194 * the file OSO001.MSG in the \OS2 directory hierarchy.
1195 *
1196 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001197static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001198os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1199{
1200 APIRET rc;
1201 ULONG msglen;
1202
1203 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1204 Py_BEGIN_ALLOW_THREADS
1205 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1206 errorcode, "oso001.msg", &msglen);
1207 Py_END_ALLOW_THREADS
1208
1209 if (rc == NO_ERROR)
1210 os2_formatmsg(msgbuf, msglen, reason);
1211 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001212 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001213 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001214
1215 return msgbuf;
1216}
1217
1218/* Set an OS/2-specific error and return NULL. OS/2 kernel
1219 errors are not in a global variable e.g. 'errno' nor are
1220 they congruent with posix error numbers. */
1221
Victor Stinner8c62be82010-05-06 00:08:46 +00001222static PyObject *
1223os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001224{
1225 char text[1024];
1226 PyObject *v;
1227
1228 os2_strerror(text, sizeof(text), code, "");
1229
1230 v = Py_BuildValue("(is)", code, text);
1231 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001232 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001233 Py_DECREF(v);
1234 }
1235 return NULL; /* Signal to Python that an Exception is Pending */
1236}
1237
1238#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001239
1240/* POSIX generic methods */
1241
Barry Warsaw53699e91996-12-10 23:23:01 +00001242static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001243posix_fildes(PyObject *fdobj, int (*func)(int))
1244{
Victor Stinner8c62be82010-05-06 00:08:46 +00001245 int fd;
1246 int res;
1247 fd = PyObject_AsFileDescriptor(fdobj);
1248 if (fd < 0)
1249 return NULL;
1250 if (!_PyVerify_fd(fd))
1251 return posix_error();
1252 Py_BEGIN_ALLOW_THREADS
1253 res = (*func)(fd);
1254 Py_END_ALLOW_THREADS
1255 if (res < 0)
1256 return posix_error();
1257 Py_INCREF(Py_None);
1258 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001259}
Guido van Rossum21142a01999-01-08 21:05:37 +00001260
1261static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001262posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001263{
Victor Stinner8c62be82010-05-06 00:08:46 +00001264 PyObject *opath1 = NULL;
1265 char *path1;
1266 int res;
1267 if (!PyArg_ParseTuple(args, format,
1268 PyUnicode_FSConverter, &opath1))
1269 return NULL;
1270 path1 = PyBytes_AsString(opath1);
1271 Py_BEGIN_ALLOW_THREADS
1272 res = (*func)(path1);
1273 Py_END_ALLOW_THREADS
1274 if (res < 0)
1275 return posix_error_with_allocated_filename(opath1);
1276 Py_DECREF(opath1);
1277 Py_INCREF(Py_None);
1278 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001279}
1280
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001281
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001282#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001283static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001284win32_1str(PyObject* args, char* func,
1285 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1286 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001287{
Victor Stinner8c62be82010-05-06 00:08:46 +00001288 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001289 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001290 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001291
Victor Stinnereb5657a2011-09-30 01:44:27 +02001292 if (PyArg_ParseTuple(args, wformat, &uni))
1293 {
1294 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1295 if (wstr == NULL)
1296 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001297 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001298 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 Py_END_ALLOW_THREADS
1300 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001301 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001302 Py_INCREF(Py_None);
1303 return Py_None;
1304 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001305 PyErr_Clear();
1306
Victor Stinner8c62be82010-05-06 00:08:46 +00001307 if (!PyArg_ParseTuple(args, format, &ansi))
1308 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001309 if (win32_warn_bytes_api())
1310 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 Py_BEGIN_ALLOW_THREADS
1312 result = funcA(ansi);
1313 Py_END_ALLOW_THREADS
1314 if (!result)
1315 return win32_error(func, ansi);
1316 Py_INCREF(Py_None);
1317 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001318
1319}
1320
1321/* This is a reimplementation of the C library's chdir function,
1322 but one that produces Win32 errors instead of DOS error codes.
1323 chdir is essentially a wrapper around SetCurrentDirectory; however,
1324 it also needs to set "magic" environment variables indicating
1325 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001326static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001327win32_chdir(LPCSTR path)
1328{
Victor Stinner8c62be82010-05-06 00:08:46 +00001329 char new_path[MAX_PATH+1];
1330 int result;
1331 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001332
Victor Stinner8c62be82010-05-06 00:08:46 +00001333 if(!SetCurrentDirectoryA(path))
1334 return FALSE;
1335 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1336 if (!result)
1337 return FALSE;
1338 /* In the ANSI API, there should not be any paths longer
1339 than MAX_PATH. */
1340 assert(result <= MAX_PATH+1);
1341 if (strncmp(new_path, "\\\\", 2) == 0 ||
1342 strncmp(new_path, "//", 2) == 0)
1343 /* UNC path, nothing to do. */
1344 return TRUE;
1345 env[1] = new_path[0];
1346 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001347}
1348
1349/* The Unicode version differs from the ANSI version
1350 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001351static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001352win32_wchdir(LPCWSTR path)
1353{
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1355 int result;
1356 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001357
Victor Stinner8c62be82010-05-06 00:08:46 +00001358 if(!SetCurrentDirectoryW(path))
1359 return FALSE;
1360 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1361 if (!result)
1362 return FALSE;
1363 if (result > MAX_PATH+1) {
1364 new_path = malloc(result * sizeof(wchar_t));
1365 if (!new_path) {
1366 SetLastError(ERROR_OUTOFMEMORY);
1367 return FALSE;
1368 }
1369 result = GetCurrentDirectoryW(result, new_path);
1370 if (!result) {
1371 free(new_path);
1372 return FALSE;
1373 }
1374 }
1375 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1376 wcsncmp(new_path, L"//", 2) == 0)
1377 /* UNC path, nothing to do. */
1378 return TRUE;
1379 env[1] = new_path[0];
1380 result = SetEnvironmentVariableW(env, new_path);
1381 if (new_path != _new_path)
1382 free(new_path);
1383 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001384}
1385#endif
1386
Martin v. Löwis14694662006-02-03 12:54:16 +00001387#ifdef MS_WINDOWS
1388/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1389 - time stamps are restricted to second resolution
1390 - file modification times suffer from forth-and-back conversions between
1391 UTC and local time
1392 Therefore, we implement our own stat, based on the Win32 API directly.
1393*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001394#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001395
1396struct win32_stat{
1397 int st_dev;
1398 __int64 st_ino;
1399 unsigned short st_mode;
1400 int st_nlink;
1401 int st_uid;
1402 int st_gid;
1403 int st_rdev;
1404 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001405 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001406 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001407 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001408 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001409 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001410 int st_ctime_nsec;
1411};
1412
1413static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1414
1415static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001416FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001417{
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1419 /* Cannot simply cast and dereference in_ptr,
1420 since it might not be aligned properly */
1421 __int64 in;
1422 memcpy(&in, in_ptr, sizeof(in));
1423 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001424 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001425}
1426
Thomas Wouters477c8d52006-05-27 19:21:47 +00001427static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001428time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001429{
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 /* XXX endianness */
1431 __int64 out;
1432 out = time_in + secs_between_epochs;
1433 out = out * 10000000 + nsec_in / 100;
1434 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435}
1436
Martin v. Löwis14694662006-02-03 12:54:16 +00001437/* Below, we *know* that ugo+r is 0444 */
1438#if _S_IREAD != 0400
1439#error Unsupported C library
1440#endif
1441static int
1442attributes_to_mode(DWORD attr)
1443{
Victor Stinner8c62be82010-05-06 00:08:46 +00001444 int m = 0;
1445 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1446 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1447 else
1448 m |= _S_IFREG;
1449 if (attr & FILE_ATTRIBUTE_READONLY)
1450 m |= 0444;
1451 else
1452 m |= 0666;
1453 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001454}
1455
1456static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001457attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001458{
Victor Stinner8c62be82010-05-06 00:08:46 +00001459 memset(result, 0, sizeof(*result));
1460 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1461 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1462 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1463 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1464 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001465 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001466 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001467 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1468 /* first clear the S_IFMT bits */
1469 result->st_mode ^= (result->st_mode & 0170000);
1470 /* now set the bits that make this a symlink */
1471 result->st_mode |= 0120000;
1472 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001473
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001475}
1476
Guido van Rossumd8faa362007-04-27 19:54:29 +00001477static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001478attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001479{
Victor Stinner8c62be82010-05-06 00:08:46 +00001480 HANDLE hFindFile;
1481 WIN32_FIND_DATAA FileData;
1482 hFindFile = FindFirstFileA(pszFile, &FileData);
1483 if (hFindFile == INVALID_HANDLE_VALUE)
1484 return FALSE;
1485 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001486 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001487 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001488 info->dwFileAttributes = FileData.dwFileAttributes;
1489 info->ftCreationTime = FileData.ftCreationTime;
1490 info->ftLastAccessTime = FileData.ftLastAccessTime;
1491 info->ftLastWriteTime = FileData.ftLastWriteTime;
1492 info->nFileSizeHigh = FileData.nFileSizeHigh;
1493 info->nFileSizeLow = FileData.nFileSizeLow;
1494/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001495 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1496 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001497 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001498}
1499
1500static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001501attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001502{
Victor Stinner8c62be82010-05-06 00:08:46 +00001503 HANDLE hFindFile;
1504 WIN32_FIND_DATAW FileData;
1505 hFindFile = FindFirstFileW(pszFile, &FileData);
1506 if (hFindFile == INVALID_HANDLE_VALUE)
1507 return FALSE;
1508 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001509 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001510 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001511 info->dwFileAttributes = FileData.dwFileAttributes;
1512 info->ftCreationTime = FileData.ftCreationTime;
1513 info->ftLastAccessTime = FileData.ftLastAccessTime;
1514 info->ftLastWriteTime = FileData.ftLastWriteTime;
1515 info->nFileSizeHigh = FileData.nFileSizeHigh;
1516 info->nFileSizeLow = FileData.nFileSizeLow;
1517/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001518 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1519 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001521}
1522
Brian Curtind25aef52011-06-13 15:16:04 -05001523/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1524static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001525static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1526 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001527static int
Brian Curtind25aef52011-06-13 15:16:04 -05001528check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001529{
Brian Curtind25aef52011-06-13 15:16:04 -05001530 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001531 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1532 DWORD);
1533
Brian Curtind25aef52011-06-13 15:16:04 -05001534 /* only recheck */
1535 if (!has_GetFinalPathNameByHandle)
1536 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001537 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001538 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1539 "GetFinalPathNameByHandleA");
1540 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1541 "GetFinalPathNameByHandleW");
1542 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1543 Py_GetFinalPathNameByHandleW;
1544 }
1545 return has_GetFinalPathNameByHandle;
1546}
1547
1548static BOOL
1549get_target_path(HANDLE hdl, wchar_t **target_path)
1550{
1551 int buf_size, result_length;
1552 wchar_t *buf;
1553
1554 /* We have a good handle to the target, use it to determine
1555 the target path name (then we'll call lstat on it). */
1556 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1557 VOLUME_NAME_DOS);
1558 if(!buf_size)
1559 return FALSE;
1560
1561 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001562 if (!buf) {
1563 SetLastError(ERROR_OUTOFMEMORY);
1564 return FALSE;
1565 }
1566
Brian Curtind25aef52011-06-13 15:16:04 -05001567 result_length = Py_GetFinalPathNameByHandleW(hdl,
1568 buf, buf_size, VOLUME_NAME_DOS);
1569
1570 if(!result_length) {
1571 free(buf);
1572 return FALSE;
1573 }
1574
1575 if(!CloseHandle(hdl)) {
1576 free(buf);
1577 return FALSE;
1578 }
1579
1580 buf[result_length] = 0;
1581
1582 *target_path = buf;
1583 return TRUE;
1584}
1585
1586static int
1587win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1588 BOOL traverse);
1589static int
1590win32_xstat_impl(const char *path, struct win32_stat *result,
1591 BOOL traverse)
1592{
Victor Stinner26de69d2011-06-17 15:15:38 +02001593 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001594 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001595 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001596 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001597 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001598 const char *dot;
1599
Brian Curtind25aef52011-06-13 15:16:04 -05001600 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001601 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1602 traverse reparse point. */
1603 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001604 }
1605
Brian Curtinf5e76d02010-11-24 13:14:05 +00001606 hFile = CreateFileA(
1607 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001608 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609 0, /* share mode */
1610 NULL, /* security attributes */
1611 OPEN_EXISTING,
1612 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001613 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1614 Because of this, calls like GetFinalPathNameByHandle will return
1615 the symlink path agin and not the actual final path. */
1616 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1617 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001618 NULL);
1619
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001620 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001621 /* Either the target doesn't exist, or we don't have access to
1622 get a handle to it. If the former, we need to return an error.
1623 If the latter, we can use attributes_from_dir. */
1624 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001625 return -1;
1626 /* Could not get attributes on open file. Fall back to
1627 reading the directory. */
1628 if (!attributes_from_dir(path, &info, &reparse_tag))
1629 /* Very strange. This should not fail now */
1630 return -1;
1631 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1632 if (traverse) {
1633 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001634 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001635 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001636 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001637 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001638 } else {
1639 if (!GetFileInformationByHandle(hFile, &info)) {
1640 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001641 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001642 }
1643 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001644 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1645 return -1;
1646
1647 /* Close the outer open file handle now that we're about to
1648 reopen it with different flags. */
1649 if (!CloseHandle(hFile))
1650 return -1;
1651
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001652 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001653 /* In order to call GetFinalPathNameByHandle we need to open
1654 the file without the reparse handling flag set. */
1655 hFile2 = CreateFileA(
1656 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1657 NULL, OPEN_EXISTING,
1658 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1659 NULL);
1660 if (hFile2 == INVALID_HANDLE_VALUE)
1661 return -1;
1662
1663 if (!get_target_path(hFile2, &target_path))
1664 return -1;
1665
1666 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001667 free(target_path);
1668 return code;
1669 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001670 } else
1671 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001672 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001673 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001674
1675 /* Set S_IEXEC if it is an .exe, .bat, ... */
1676 dot = strrchr(path, '.');
1677 if (dot) {
1678 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1679 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1680 result->st_mode |= 0111;
1681 }
1682 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001683}
1684
1685static int
Brian Curtind25aef52011-06-13 15:16:04 -05001686win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1687 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001688{
1689 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001690 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001691 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001692 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001693 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001694 const wchar_t *dot;
1695
Brian Curtind25aef52011-06-13 15:16:04 -05001696 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001697 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1698 traverse reparse point. */
1699 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001700 }
1701
Brian Curtinf5e76d02010-11-24 13:14:05 +00001702 hFile = CreateFileW(
1703 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001704 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 0, /* share mode */
1706 NULL, /* security attributes */
1707 OPEN_EXISTING,
1708 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001709 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1710 Because of this, calls like GetFinalPathNameByHandle will return
1711 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001712 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001713 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001714 NULL);
1715
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001716 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001717 /* Either the target doesn't exist, or we don't have access to
1718 get a handle to it. If the former, we need to return an error.
1719 If the latter, we can use attributes_from_dir. */
1720 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001721 return -1;
1722 /* Could not get attributes on open file. Fall back to
1723 reading the directory. */
1724 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1725 /* Very strange. This should not fail now */
1726 return -1;
1727 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1728 if (traverse) {
1729 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001730 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001731 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001732 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001733 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001734 } else {
1735 if (!GetFileInformationByHandle(hFile, &info)) {
1736 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001737 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001738 }
1739 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001740 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1741 return -1;
1742
1743 /* Close the outer open file handle now that we're about to
1744 reopen it with different flags. */
1745 if (!CloseHandle(hFile))
1746 return -1;
1747
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001748 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001749 /* In order to call GetFinalPathNameByHandle we need to open
1750 the file without the reparse handling flag set. */
1751 hFile2 = CreateFileW(
1752 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1753 NULL, OPEN_EXISTING,
1754 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1755 NULL);
1756 if (hFile2 == INVALID_HANDLE_VALUE)
1757 return -1;
1758
1759 if (!get_target_path(hFile2, &target_path))
1760 return -1;
1761
1762 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001763 free(target_path);
1764 return code;
1765 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001766 } else
1767 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001768 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001769 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001770
1771 /* Set S_IEXEC if it is an .exe, .bat, ... */
1772 dot = wcsrchr(path, '.');
1773 if (dot) {
1774 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1775 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1776 result->st_mode |= 0111;
1777 }
1778 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001779}
1780
1781static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001782win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001783{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001784 /* Protocol violation: we explicitly clear errno, instead of
1785 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001786 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001787 errno = 0;
1788 return code;
1789}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001790
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001791static int
1792win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1793{
1794 /* Protocol violation: we explicitly clear errno, instead of
1795 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001796 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001797 errno = 0;
1798 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001799}
Brian Curtind25aef52011-06-13 15:16:04 -05001800/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001801
1802 In Posix, stat automatically traverses symlinks and returns the stat
1803 structure for the target. In Windows, the equivalent GetFileAttributes by
1804 default does not traverse symlinks and instead returns attributes for
1805 the symlink.
1806
1807 Therefore, win32_lstat will get the attributes traditionally, and
1808 win32_stat will first explicitly resolve the symlink target and then will
1809 call win32_lstat on that result.
1810
Ezio Melotti4969f702011-03-15 05:59:46 +02001811 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001812
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001813static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001814win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001815{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001816 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001817}
1818
Victor Stinner8c62be82010-05-06 00:08:46 +00001819static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001820win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001821{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001822 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001823}
1824
1825static int
1826win32_stat(const char* path, struct win32_stat *result)
1827{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001828 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001829}
1830
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001831static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001832win32_stat_w(const wchar_t* path, struct win32_stat *result)
1833{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001834 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001835}
1836
1837static int
1838win32_fstat(int file_number, struct win32_stat *result)
1839{
Victor Stinner8c62be82010-05-06 00:08:46 +00001840 BY_HANDLE_FILE_INFORMATION info;
1841 HANDLE h;
1842 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001843
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001844 if (!_PyVerify_fd(file_number))
1845 h = INVALID_HANDLE_VALUE;
1846 else
1847 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001848
Victor Stinner8c62be82010-05-06 00:08:46 +00001849 /* Protocol violation: we explicitly clear errno, instead of
1850 setting it to a POSIX error. Callers should use GetLastError. */
1851 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001852
Victor Stinner8c62be82010-05-06 00:08:46 +00001853 if (h == INVALID_HANDLE_VALUE) {
1854 /* This is really a C library error (invalid file handle).
1855 We set the Win32 error to the closes one matching. */
1856 SetLastError(ERROR_INVALID_HANDLE);
1857 return -1;
1858 }
1859 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001860
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 type = GetFileType(h);
1862 if (type == FILE_TYPE_UNKNOWN) {
1863 DWORD error = GetLastError();
1864 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001865 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001866 }
1867 /* else: valid but unknown file */
1868 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001869
Victor Stinner8c62be82010-05-06 00:08:46 +00001870 if (type != FILE_TYPE_DISK) {
1871 if (type == FILE_TYPE_CHAR)
1872 result->st_mode = _S_IFCHR;
1873 else if (type == FILE_TYPE_PIPE)
1874 result->st_mode = _S_IFIFO;
1875 return 0;
1876 }
1877
1878 if (!GetFileInformationByHandle(h, &info)) {
1879 return -1;
1880 }
1881
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001882 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001883 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001884 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1885 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001886}
1887
1888#endif /* MS_WINDOWS */
1889
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001890PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001891"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001892This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001893 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001894or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1895\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001896Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1897or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001898\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001899See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001900
1901static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001902 {"st_mode", "protection bits"},
1903 {"st_ino", "inode"},
1904 {"st_dev", "device"},
1905 {"st_nlink", "number of hard links"},
1906 {"st_uid", "user ID of owner"},
1907 {"st_gid", "group ID of owner"},
1908 {"st_size", "total size, in bytes"},
1909 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1910 {NULL, "integer time of last access"},
1911 {NULL, "integer time of last modification"},
1912 {NULL, "integer time of last change"},
1913 {"st_atime", "time of last access"},
1914 {"st_mtime", "time of last modification"},
1915 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001916 {"st_atime_ns", "time of last access in nanoseconds"},
1917 {"st_mtime_ns", "time of last modification in nanoseconds"},
1918 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001919#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001921#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001922#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001923 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001924#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001925#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001926 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001927#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001928#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001930#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001931#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001932 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001933#endif
1934#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001936#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001938};
1939
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001940#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001941#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001942#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001943#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001944#endif
1945
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001946#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001947#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1948#else
1949#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1950#endif
1951
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001952#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001953#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1954#else
1955#define ST_RDEV_IDX ST_BLOCKS_IDX
1956#endif
1957
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001958#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1959#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1960#else
1961#define ST_FLAGS_IDX ST_RDEV_IDX
1962#endif
1963
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001964#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001965#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001966#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001967#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001968#endif
1969
1970#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1971#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1972#else
1973#define ST_BIRTHTIME_IDX ST_GEN_IDX
1974#endif
1975
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001976static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 "stat_result", /* name */
1978 stat_result__doc__, /* doc */
1979 stat_result_fields,
1980 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001981};
1982
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001983PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001984"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1985This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001986 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001987or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001988\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001989See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001990
1991static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001992 {"f_bsize", },
1993 {"f_frsize", },
1994 {"f_blocks", },
1995 {"f_bfree", },
1996 {"f_bavail", },
1997 {"f_files", },
1998 {"f_ffree", },
1999 {"f_favail", },
2000 {"f_flag", },
2001 {"f_namemax",},
2002 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002003};
2004
2005static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002006 "statvfs_result", /* name */
2007 statvfs_result__doc__, /* doc */
2008 statvfs_result_fields,
2009 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002010};
2011
Ross Lagerwall7807c352011-03-17 20:20:30 +02002012#if defined(HAVE_WAITID) && !defined(__APPLE__)
2013PyDoc_STRVAR(waitid_result__doc__,
2014"waitid_result: Result from waitid.\n\n\
2015This object may be accessed either as a tuple of\n\
2016 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2017or via the attributes si_pid, si_uid, and so on.\n\
2018\n\
2019See os.waitid for more information.");
2020
2021static PyStructSequence_Field waitid_result_fields[] = {
2022 {"si_pid", },
2023 {"si_uid", },
2024 {"si_signo", },
2025 {"si_status", },
2026 {"si_code", },
2027 {0}
2028};
2029
2030static PyStructSequence_Desc waitid_result_desc = {
2031 "waitid_result", /* name */
2032 waitid_result__doc__, /* doc */
2033 waitid_result_fields,
2034 5
2035};
2036static PyTypeObject WaitidResultType;
2037#endif
2038
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002039static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002040static PyTypeObject StatResultType;
2041static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002042#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002043static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002044#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002045static newfunc structseq_new;
2046
2047static PyObject *
2048statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2049{
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 PyStructSequence *result;
2051 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002052
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 result = (PyStructSequence*)structseq_new(type, args, kwds);
2054 if (!result)
2055 return NULL;
2056 /* If we have been initialized from a tuple,
2057 st_?time might be set to None. Initialize it
2058 from the int slots. */
2059 for (i = 7; i <= 9; i++) {
2060 if (result->ob_item[i+3] == Py_None) {
2061 Py_DECREF(Py_None);
2062 Py_INCREF(result->ob_item[i]);
2063 result->ob_item[i+3] = result->ob_item[i];
2064 }
2065 }
2066 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002067}
2068
2069
2070
2071/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002072static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002073
2074PyDoc_STRVAR(stat_float_times__doc__,
2075"stat_float_times([newval]) -> oldval\n\n\
2076Determine whether os.[lf]stat represents time stamps as float objects.\n\
2077If newval is True, future calls to stat() return floats, if it is False,\n\
2078future calls return ints. \n\
2079If newval is omitted, return the current setting.\n");
2080
2081static PyObject*
2082stat_float_times(PyObject* self, PyObject *args)
2083{
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 int newval = -1;
2085 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2086 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002087 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2088 "stat_float_times() is deprecated",
2089 1))
2090 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002091 if (newval == -1)
2092 /* Return old value */
2093 return PyBool_FromLong(_stat_float_times);
2094 _stat_float_times = newval;
2095 Py_INCREF(Py_None);
2096 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002097}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002098
Larry Hastings6fe20b32012-04-19 15:07:49 -07002099static PyObject *billion = NULL;
2100
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002101static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002102fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002103{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002104 PyObject *s = _PyLong_FromTime_t(sec);
2105 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2106 PyObject *s_in_ns = NULL;
2107 PyObject *ns_total = NULL;
2108 PyObject *float_s = NULL;
2109
2110 if (!(s && ns_fractional))
2111 goto exit;
2112
2113 s_in_ns = PyNumber_Multiply(s, billion);
2114 if (!s_in_ns)
2115 goto exit;
2116
2117 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2118 if (!ns_total)
2119 goto exit;
2120
Victor Stinner4195b5c2012-02-08 23:03:19 +01002121 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002122 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2123 if (!float_s)
2124 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002125 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002126 else {
2127 float_s = s;
2128 Py_INCREF(float_s);
2129 }
2130
2131 PyStructSequence_SET_ITEM(v, index, s);
2132 PyStructSequence_SET_ITEM(v, index+3, float_s);
2133 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2134 s = NULL;
2135 float_s = NULL;
2136 ns_total = NULL;
2137exit:
2138 Py_XDECREF(s);
2139 Py_XDECREF(ns_fractional);
2140 Py_XDECREF(s_in_ns);
2141 Py_XDECREF(ns_total);
2142 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002143}
2144
Tim Peters5aa91602002-01-30 05:46:57 +00002145/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002146 (used by posix_stat() and posix_fstat()) */
2147static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002148_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002149{
Victor Stinner8c62be82010-05-06 00:08:46 +00002150 unsigned long ansec, mnsec, cnsec;
2151 PyObject *v = PyStructSequence_New(&StatResultType);
2152 if (v == NULL)
2153 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002154
Victor Stinner8c62be82010-05-06 00:08:46 +00002155 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002156#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002157 PyStructSequence_SET_ITEM(v, 1,
2158 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002159#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002160 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002161#endif
2162#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002163 PyStructSequence_SET_ITEM(v, 2,
2164 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002165#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002166 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002167#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002168 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
2169 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
2170 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00002171#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002172 PyStructSequence_SET_ITEM(v, 6,
2173 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002174#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002175 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002176#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002177
Martin v. Löwis14694662006-02-03 12:54:16 +00002178#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002179 ansec = st->st_atim.tv_nsec;
2180 mnsec = st->st_mtim.tv_nsec;
2181 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002182#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002183 ansec = st->st_atimespec.tv_nsec;
2184 mnsec = st->st_mtimespec.tv_nsec;
2185 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002186#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002187 ansec = st->st_atime_nsec;
2188 mnsec = st->st_mtime_nsec;
2189 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002190#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002191 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002192#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002193 fill_time(v, 7, st->st_atime, ansec);
2194 fill_time(v, 8, st->st_mtime, mnsec);
2195 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002196
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002197#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002198 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2199 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002200#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002201#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002202 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2203 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002204#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002205#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002206 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2207 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002208#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002209#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002210 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2211 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002212#endif
2213#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002215 PyObject *val;
2216 unsigned long bsec,bnsec;
2217 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002218#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002219 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002220#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002221 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002222#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002223 if (_stat_float_times) {
2224 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2225 } else {
2226 val = PyLong_FromLong((long)bsec);
2227 }
2228 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2229 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002230 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002231#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002232#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002233 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2234 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002235#endif
Fred Drake699f3522000-06-29 21:12:41 +00002236
Victor Stinner8c62be82010-05-06 00:08:46 +00002237 if (PyErr_Occurred()) {
2238 Py_DECREF(v);
2239 return NULL;
2240 }
Fred Drake699f3522000-06-29 21:12:41 +00002241
Victor Stinner8c62be82010-05-06 00:08:46 +00002242 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002243}
2244
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002245/* POSIX methods */
2246
Guido van Rossum94f6f721999-01-06 18:42:14 +00002247
2248static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002249posix_do_stat(char *function_name, path_t *path,
2250 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002251{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002252 STRUCT_STAT st;
2253 int result;
2254
2255#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2256 if (follow_symlinks_specified(function_name, follow_symlinks))
2257 return NULL;
2258#endif
2259
2260 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2261 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2262 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2263 return NULL;
2264
2265 Py_BEGIN_ALLOW_THREADS
2266 if (path->fd != -1)
2267 result = FSTAT(path->fd, &st);
2268 else
2269#ifdef MS_WINDOWS
2270 if (path->wide) {
2271 if (follow_symlinks)
2272 result = win32_stat_w(path->wide, &st);
2273 else
2274 result = win32_lstat_w(path->wide, &st);
2275 }
2276 else
2277#endif
2278#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2279 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2280 result = LSTAT(path->narrow, &st);
2281 else
2282#endif
2283#ifdef HAVE_FSTATAT
2284 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2285 result = fstatat(dir_fd, path->narrow, &st,
2286 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2287 else
2288#endif
2289 result = STAT(path->narrow, &st);
2290 Py_END_ALLOW_THREADS
2291
2292 if (result != 0)
2293 return path_error("stat", path);
2294
2295 return _pystat_fromstructstat(&st);
2296}
2297
2298PyDoc_STRVAR(posix_stat__doc__,
2299"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2300Perform a stat system call on the given path.\n\
2301\n\
2302path may be specified as either a string or as an open file descriptor.\n\
2303\n\
2304If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2305 and path should be relative; path will then be relative to that directory.\n\
2306 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2307 it will raise a NotImplementedError.\n\
2308If follow_symlinks is False, and the last element of the path is a symbolic\n\
2309 link, stat will examine the symbolic link itself instead of the file the\n\
2310 link points to.\n\
2311It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2312 an open file descriptor.");
2313
2314static PyObject *
2315posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2316{
2317 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2318 path_t path;
2319 int dir_fd = DEFAULT_DIR_FD;
2320 int follow_symlinks = 1;
2321 PyObject *return_value;
2322
2323 memset(&path, 0, sizeof(path));
2324 path.allow_fd = 1;
2325 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2326 path_converter, &path,
2327#ifdef HAVE_FSTATAT
2328 dir_fd_converter, &dir_fd,
2329#else
2330 dir_fd_unavailable, &dir_fd,
2331#endif
2332 &follow_symlinks))
2333 return NULL;
2334 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2335 path_cleanup(&path);
2336 return return_value;
2337}
2338
2339PyDoc_STRVAR(posix_lstat__doc__,
2340"lstat(path, *, dir_fd=None) -> stat result\n\n\
2341Like stat(), but do not follow symbolic links.\n\
2342Equivalent to stat(path, follow_symlinks=False).");
2343
2344static PyObject *
2345posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2346{
2347 static char *keywords[] = {"path", "dir_fd", NULL};
2348 path_t path;
2349 int dir_fd = DEFAULT_DIR_FD;
2350 int follow_symlinks = 0;
2351 PyObject *return_value;
2352
2353 memset(&path, 0, sizeof(path));
2354 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2355 path_converter, &path,
2356#ifdef HAVE_FSTATAT
2357 dir_fd_converter, &dir_fd
2358#else
2359 dir_fd_unavailable, &dir_fd
2360#endif
2361 ))
2362 return NULL;
2363 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2364 path_cleanup(&path);
2365 return return_value;
2366}
2367
2368PyDoc_STRVAR(posix_access__doc__,
2369"access(path, mode, *, dir_fd=None, effective_ids=False,\
2370 follow_symlinks=True)\n\n\
2371Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2372False otherwise.\n\
2373\n\
2374If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2375 and path should be relative; path will then be relative to that directory.\n\
2376If effective_ids is True, access will use the effective uid/gid instead of\n\
2377 the real uid/gid.\n\
2378If follow_symlinks is False, and the last element of the path is a symbolic\n\
2379 link, access will examine the symbolic link itself instead of the file the\n\
2380 link points to.\n\
2381dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2382 on your platform. If they are unavailable, using them will raise a\n\
2383 NotImplementedError.\n\
2384\n\
2385Note that most operations will use the effective uid/gid, therefore this\n\
2386 routine can be used in a suid/sgid environment to test if the invoking user\n\
2387 has the specified access to the path.\n\
2388The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2389 of R_OK, W_OK, and X_OK.");
2390
2391static PyObject *
2392posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2393{
2394 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2395 "follow_symlinks", NULL};
2396 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002397 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002398 int dir_fd = DEFAULT_DIR_FD;
2399 int effective_ids = 0;
2400 int follow_symlinks = 1;
2401 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002402
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002403#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002404 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002405#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002406 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002407#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002408
2409 memset(&path, 0, sizeof(path));
2410 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2411 path_converter, &path, &mode,
2412#ifdef HAVE_FACCESSAT
2413 dir_fd_converter, &dir_fd,
2414#else
2415 dir_fd_unavailable, &dir_fd,
2416#endif
2417 &effective_ids, &follow_symlinks))
2418 return NULL;
2419
2420#ifndef HAVE_FACCESSAT
2421 if (follow_symlinks_specified("access", follow_symlinks))
2422 goto exit;
2423
2424 if (effective_ids) {
2425 argument_unavailable_error("access", "effective_ids");
2426 goto exit;
2427 }
2428#endif
2429
2430#ifdef MS_WINDOWS
2431 Py_BEGIN_ALLOW_THREADS
2432 if (path.wide != NULL)
2433 attr = GetFileAttributesW(path.wide);
2434 else
2435 attr = GetFileAttributesA(path.narrow);
2436 Py_END_ALLOW_THREADS
2437
2438 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002439 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002440 * * we didn't get a -1, and
2441 * * write access wasn't requested,
2442 * * or the file isn't read-only,
2443 * * or it's a directory.
2444 * (Directories cannot be read-only on Windows.)
2445 */
2446 return_value = PyBool_FromLong(
2447 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002448 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002449 !(attr & FILE_ATTRIBUTE_READONLY) ||
2450 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2451#else
2452
2453 Py_BEGIN_ALLOW_THREADS
2454#ifdef HAVE_FACCESSAT
2455 if ((dir_fd != DEFAULT_DIR_FD) ||
2456 effective_ids ||
2457 !follow_symlinks) {
2458 int flags = 0;
2459 if (!follow_symlinks)
2460 flags |= AT_SYMLINK_NOFOLLOW;
2461 if (effective_ids)
2462 flags |= AT_EACCESS;
2463 result = faccessat(dir_fd, path.narrow, mode, flags);
2464 }
2465 else
2466#endif
2467 result = access(path.narrow, mode);
2468 Py_END_ALLOW_THREADS
2469 return_value = PyBool_FromLong(!result);
2470#endif
2471
2472#ifndef HAVE_FACCESSAT
2473exit:
2474#endif
2475 path_cleanup(&path);
2476 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002477}
2478
Guido van Rossumd371ff11999-01-25 16:12:23 +00002479#ifndef F_OK
2480#define F_OK 0
2481#endif
2482#ifndef R_OK
2483#define R_OK 4
2484#endif
2485#ifndef W_OK
2486#define W_OK 2
2487#endif
2488#ifndef X_OK
2489#define X_OK 1
2490#endif
2491
2492#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002493PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002494"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002495Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002496
2497static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002498posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002499{
Victor Stinner8c62be82010-05-06 00:08:46 +00002500 int id;
2501 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002502
Victor Stinner8c62be82010-05-06 00:08:46 +00002503 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2504 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002505
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002506#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002507 /* file descriptor 0 only, the default input device (stdin) */
2508 if (id == 0) {
2509 ret = ttyname();
2510 }
2511 else {
2512 ret = NULL;
2513 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002514#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002515 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002516#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002517 if (ret == NULL)
2518 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002519 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002520}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002521#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002522
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002523#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002524PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002525"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002526Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002527
2528static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002529posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002530{
Victor Stinner8c62be82010-05-06 00:08:46 +00002531 char *ret;
2532 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002533
Greg Wardb48bc172000-03-01 21:51:56 +00002534#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002535 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002536#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002537 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002538#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002539 if (ret == NULL)
2540 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002541 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002542}
2543#endif
2544
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002545PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002546"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002547Change the current working directory to the specified path.\n\
2548\n\
2549path may always be specified as a string.\n\
2550On some platforms, path may also be specified as an open file descriptor.\n\
2551 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002552
Barry Warsaw53699e91996-12-10 23:23:01 +00002553static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002554posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002555{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002556 path_t path;
2557 int result;
2558 PyObject *return_value = NULL;
2559 static char *keywords[] = {"path", NULL};
2560
2561 memset(&path, 0, sizeof(path));
2562#ifdef HAVE_FCHDIR
2563 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002564#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002565 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2566 path_converter, &path
2567 ))
2568 return NULL;
2569
2570 Py_BEGIN_ALLOW_THREADS
2571#ifdef MS_WINDOWS
2572 if (path.wide)
2573 result = win32_wchdir(path.wide);
2574 else
2575 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002576 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002577#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2578 result = _chdir2(path.narrow);
2579#else
2580#ifdef HAVE_FCHDIR
2581 if (path.fd != -1)
2582 result = fchdir(path.fd);
2583 else
2584#endif
2585 result = chdir(path.narrow);
2586#endif
2587 Py_END_ALLOW_THREADS
2588
2589 if (result) {
2590 return_value = path_error("chdir", &path);
2591 goto exit;
2592 }
2593
2594 return_value = Py_None;
2595 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002596
Larry Hastings9cf065c2012-06-22 16:30:09 -07002597exit:
2598 path_cleanup(&path);
2599 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002600}
2601
Fred Drake4d1e64b2002-04-15 19:40:07 +00002602#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002603PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002604"fchdir(fd)\n\n\
2605Change to the directory of the given file descriptor. fd must be\n\
2606opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002607
2608static PyObject *
2609posix_fchdir(PyObject *self, PyObject *fdobj)
2610{
Victor Stinner8c62be82010-05-06 00:08:46 +00002611 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002612}
2613#endif /* HAVE_FCHDIR */
2614
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002615
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002616PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002617"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2618Change the access permissions of a file.\n\
2619\n\
2620path may always be specified as a string.\n\
2621On some platforms, path may also be specified as an open file descriptor.\n\
2622 If this functionality is unavailable, using it raises an exception.\n\
2623If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2624 and path should be relative; path will then be relative to that directory.\n\
2625If follow_symlinks is False, and the last element of the path is a symbolic\n\
2626 link, chmod will modify the symbolic link itself instead of the file the\n\
2627 link points to.\n\
2628It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2629 an open file descriptor.\n\
2630dir_fd and follow_symlinks may not be implemented on your platform.\n\
2631 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002632
Barry Warsaw53699e91996-12-10 23:23:01 +00002633static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002635{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002636 path_t path;
2637 int mode;
2638 int dir_fd = DEFAULT_DIR_FD;
2639 int follow_symlinks = 1;
2640 int result;
2641 PyObject *return_value = NULL;
2642 static char *keywords[] = {"path", "mode", "dir_fd",
2643 "follow_symlinks", NULL};
2644
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002645#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002646 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002647#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002648
Larry Hastings9cf065c2012-06-22 16:30:09 -07002649#ifdef HAVE_FCHMODAT
2650 int fchmodat_nofollow_unsupported = 0;
2651#endif
2652
2653 memset(&path, 0, sizeof(path));
2654#ifdef HAVE_FCHMOD
2655 path.allow_fd = 1;
2656#endif
2657 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2658 path_converter, &path,
2659 &mode,
2660#ifdef HAVE_FCHMODAT
2661 dir_fd_converter, &dir_fd,
2662#else
2663 dir_fd_unavailable, &dir_fd,
2664#endif
2665 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002666 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002667
2668#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2669 if (follow_symlinks_specified("chmod", follow_symlinks))
2670 goto exit;
2671#endif
2672
2673#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002674 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002675 if (path.wide)
2676 attr = GetFileAttributesW(path.wide);
2677 else
2678 attr = GetFileAttributesA(path.narrow);
2679 if (attr == 0xFFFFFFFF)
2680 result = 0;
2681 else {
2682 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 attr &= ~FILE_ATTRIBUTE_READONLY;
2684 else
2685 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002686 if (path.wide)
2687 result = SetFileAttributesW(path.wide, attr);
2688 else
2689 result = SetFileAttributesA(path.narrow, attr);
2690 }
2691 Py_END_ALLOW_THREADS
2692
2693 if (!result) {
2694 return_value = win32_error_object("chmod", path.object);
2695 goto exit;
2696 }
2697#else /* MS_WINDOWS */
2698 Py_BEGIN_ALLOW_THREADS
2699#ifdef HAVE_FCHMOD
2700 if (path.fd != -1)
2701 result = fchmod(path.fd, mode);
2702 else
2703#endif
2704#ifdef HAVE_LCHMOD
2705 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2706 result = lchmod(path.narrow, mode);
2707 else
2708#endif
2709#ifdef HAVE_FCHMODAT
2710 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2711 /*
2712 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2713 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002714 * and then says it isn't implemented yet.
2715 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716 *
2717 * Once it is supported, os.chmod will automatically
2718 * support dir_fd and follow_symlinks=False. (Hopefully.)
2719 * Until then, we need to be careful what exception we raise.
2720 */
2721 result = fchmodat(dir_fd, path.narrow, mode,
2722 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2723 /*
2724 * But wait! We can't throw the exception without allowing threads,
2725 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2726 */
2727 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002728 result &&
2729 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2730 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002731 }
2732 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002733#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002734 result = chmod(path.narrow, mode);
2735 Py_END_ALLOW_THREADS
2736
2737 if (result) {
2738#ifdef HAVE_FCHMODAT
2739 if (fchmodat_nofollow_unsupported) {
2740 if (dir_fd != DEFAULT_DIR_FD)
2741 dir_fd_and_follow_symlinks_invalid("chmod",
2742 dir_fd, follow_symlinks);
2743 else
2744 follow_symlinks_specified("chmod", follow_symlinks);
2745 }
2746 else
2747#endif
2748 return_value = path_error("chmod", &path);
2749 goto exit;
2750 }
2751#endif
2752
2753 Py_INCREF(Py_None);
2754 return_value = Py_None;
2755exit:
2756 path_cleanup(&path);
2757 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002758}
2759
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760
Christian Heimes4e30a842007-11-30 22:12:06 +00002761#ifdef HAVE_FCHMOD
2762PyDoc_STRVAR(posix_fchmod__doc__,
2763"fchmod(fd, mode)\n\n\
2764Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002765descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002766
2767static PyObject *
2768posix_fchmod(PyObject *self, PyObject *args)
2769{
Victor Stinner8c62be82010-05-06 00:08:46 +00002770 int fd, mode, res;
2771 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2772 return NULL;
2773 Py_BEGIN_ALLOW_THREADS
2774 res = fchmod(fd, mode);
2775 Py_END_ALLOW_THREADS
2776 if (res < 0)
2777 return posix_error();
2778 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002779}
2780#endif /* HAVE_FCHMOD */
2781
2782#ifdef HAVE_LCHMOD
2783PyDoc_STRVAR(posix_lchmod__doc__,
2784"lchmod(path, mode)\n\n\
2785Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002786affects the link itself rather than the target.\n\
2787Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002788
2789static PyObject *
2790posix_lchmod(PyObject *self, PyObject *args)
2791{
Victor Stinner8c62be82010-05-06 00:08:46 +00002792 PyObject *opath;
2793 char *path;
2794 int i;
2795 int res;
2796 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2797 &opath, &i))
2798 return NULL;
2799 path = PyBytes_AsString(opath);
2800 Py_BEGIN_ALLOW_THREADS
2801 res = lchmod(path, i);
2802 Py_END_ALLOW_THREADS
2803 if (res < 0)
2804 return posix_error_with_allocated_filename(opath);
2805 Py_DECREF(opath);
2806 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002807}
2808#endif /* HAVE_LCHMOD */
2809
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002810
Thomas Wouterscf297e42007-02-23 15:07:44 +00002811#ifdef HAVE_CHFLAGS
2812PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002813"chflags(path, flags, *, follow_symlinks=True)\n\n\
2814Set file flags.\n\
2815\n\
2816If follow_symlinks is False, and the last element of the path is a symbolic\n\
2817 link, chflags will change flags on the symbolic link itself instead of the\n\
2818 file the link points to.\n\
2819follow_symlinks may not be implemented on your platform. If it is\n\
2820unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002821
2822static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002823posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002824{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002826 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002827 int follow_symlinks = 1;
2828 int result;
2829 PyObject *return_value;
2830 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2831
2832 memset(&path, 0, sizeof(path));
2833 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2834 path_converter, &path,
2835 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002836 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002837
2838#ifndef HAVE_LCHFLAGS
2839 if (follow_symlinks_specified("chflags", follow_symlinks))
2840 goto exit;
2841#endif
2842
Victor Stinner8c62be82010-05-06 00:08:46 +00002843 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844#ifdef HAVE_LCHFLAGS
2845 if (!follow_symlinks)
2846 result = lchflags(path.narrow, flags);
2847 else
2848#endif
2849 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002850 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002851
2852 if (result) {
2853 return_value = path_posix_error("chflags", &path);
2854 goto exit;
2855 }
2856
2857 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002858 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859
2860exit:
2861 path_cleanup(&path);
2862 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002863}
2864#endif /* HAVE_CHFLAGS */
2865
2866#ifdef HAVE_LCHFLAGS
2867PyDoc_STRVAR(posix_lchflags__doc__,
2868"lchflags(path, flags)\n\n\
2869Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002870This function will not follow symbolic links.\n\
2871Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002872
2873static PyObject *
2874posix_lchflags(PyObject *self, PyObject *args)
2875{
Victor Stinner8c62be82010-05-06 00:08:46 +00002876 PyObject *opath;
2877 char *path;
2878 unsigned long flags;
2879 int res;
2880 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2881 PyUnicode_FSConverter, &opath, &flags))
2882 return NULL;
2883 path = PyBytes_AsString(opath);
2884 Py_BEGIN_ALLOW_THREADS
2885 res = lchflags(path, flags);
2886 Py_END_ALLOW_THREADS
2887 if (res < 0)
2888 return posix_error_with_allocated_filename(opath);
2889 Py_DECREF(opath);
2890 Py_INCREF(Py_None);
2891 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002892}
2893#endif /* HAVE_LCHFLAGS */
2894
Martin v. Löwis244edc82001-10-04 22:44:26 +00002895#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002896PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002897"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002898Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002899
2900static PyObject *
2901posix_chroot(PyObject *self, PyObject *args)
2902{
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002904}
2905#endif
2906
Guido van Rossum21142a01999-01-08 21:05:37 +00002907#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002908PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002909"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002910force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002911
2912static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002913posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002914{
Stefan Krah0e803b32010-11-26 16:16:47 +00002915 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002916}
2917#endif /* HAVE_FSYNC */
2918
Ross Lagerwall7807c352011-03-17 20:20:30 +02002919#ifdef HAVE_SYNC
2920PyDoc_STRVAR(posix_sync__doc__,
2921"sync()\n\n\
2922Force write of everything to disk.");
2923
2924static PyObject *
2925posix_sync(PyObject *self, PyObject *noargs)
2926{
2927 Py_BEGIN_ALLOW_THREADS
2928 sync();
2929 Py_END_ALLOW_THREADS
2930 Py_RETURN_NONE;
2931}
2932#endif
2933
Guido van Rossum21142a01999-01-08 21:05:37 +00002934#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002935
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002936#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002937extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2938#endif
2939
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002940PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002941"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002942force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002943 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002944
2945static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002946posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002947{
Stefan Krah0e803b32010-11-26 16:16:47 +00002948 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002949}
2950#endif /* HAVE_FDATASYNC */
2951
2952
Fredrik Lundh10723342000-07-10 16:38:09 +00002953#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002954PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002955"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2956Change the owner and group id of path to the numeric uid and gid.\n\
2957\n\
2958path may always be specified as a string.\n\
2959On some platforms, path may also be specified as an open file descriptor.\n\
2960 If this functionality is unavailable, using it raises an exception.\n\
2961If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2962 and path should be relative; path will then be relative to that directory.\n\
2963If follow_symlinks is False, and the last element of the path is a symbolic\n\
2964 link, chown will modify the symbolic link itself instead of the file the\n\
2965 link points to.\n\
2966It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2967 an open file descriptor.\n\
2968dir_fd and follow_symlinks may not be implemented on your platform.\n\
2969 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002970
Barry Warsaw53699e91996-12-10 23:23:01 +00002971static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002973{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002974 path_t path;
2975 long uid_l, gid_l;
2976 uid_t uid;
2977 gid_t gid;
2978 int dir_fd = DEFAULT_DIR_FD;
2979 int follow_symlinks = 1;
2980 int result;
2981 PyObject *return_value = NULL;
2982 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2983 "follow_symlinks", NULL};
2984
2985 memset(&path, 0, sizeof(path));
2986#ifdef HAVE_FCHOWN
2987 path.allow_fd = 1;
2988#endif
2989 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2990 path_converter, &path,
2991 &uid_l, &gid_l,
2992#ifdef HAVE_FCHOWNAT
2993 dir_fd_converter, &dir_fd,
2994#else
2995 dir_fd_unavailable, &dir_fd,
2996#endif
2997 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002998 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002999
3000#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3001 if (follow_symlinks_specified("chown", follow_symlinks))
3002 goto exit;
3003#endif
3004 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3005 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3006 goto exit;
3007
3008#ifdef __APPLE__
3009 /*
3010 * This is for Mac OS X 10.3, which doesn't have lchown.
3011 * (But we still have an lchown symbol because of weak-linking.)
3012 * It doesn't have fchownat either. So there's no possibility
3013 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003014 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003015 if ((!follow_symlinks) && (lchown == NULL)) {
3016 follow_symlinks_specified("chown", follow_symlinks);
3017 goto exit;
3018 }
3019#endif
3020
Victor Stinner8c62be82010-05-06 00:08:46 +00003021 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003022 uid = (uid_t)uid_l;
3023 gid = (uid_t)gid_l;
3024#ifdef HAVE_FCHOWN
3025 if (path.fd != -1)
3026 result = fchown(path.fd, uid, gid);
3027 else
3028#endif
3029#ifdef HAVE_LCHOWN
3030 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3031 result = lchown(path.narrow, uid, gid);
3032 else
3033#endif
3034#ifdef HAVE_FCHOWNAT
3035 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3036 result = fchownat(dir_fd, path.narrow, uid, gid,
3037 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3038 else
3039#endif
3040 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003041 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003042
3043 if (result) {
3044 return_value = path_posix_error("chown", &path);
3045 goto exit;
3046 }
3047
3048 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003049 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003050
3051exit:
3052 path_cleanup(&path);
3053 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003054}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003055#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003056
Christian Heimes4e30a842007-11-30 22:12:06 +00003057#ifdef HAVE_FCHOWN
3058PyDoc_STRVAR(posix_fchown__doc__,
3059"fchown(fd, uid, gid)\n\n\
3060Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003061fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003062
3063static PyObject *
3064posix_fchown(PyObject *self, PyObject *args)
3065{
Victor Stinner8c62be82010-05-06 00:08:46 +00003066 int fd;
3067 long uid, gid;
3068 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02003069 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003070 return NULL;
3071 Py_BEGIN_ALLOW_THREADS
3072 res = fchown(fd, (uid_t) uid, (gid_t) gid);
3073 Py_END_ALLOW_THREADS
3074 if (res < 0)
3075 return posix_error();
3076 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003077}
3078#endif /* HAVE_FCHOWN */
3079
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003080#ifdef HAVE_LCHOWN
3081PyDoc_STRVAR(posix_lchown__doc__,
3082"lchown(path, uid, gid)\n\n\
3083Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003084This function will not follow symbolic links.\n\
3085Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003086
3087static PyObject *
3088posix_lchown(PyObject *self, PyObject *args)
3089{
Victor Stinner8c62be82010-05-06 00:08:46 +00003090 PyObject *opath;
3091 char *path;
3092 long uid, gid;
3093 int res;
3094 if (!PyArg_ParseTuple(args, "O&ll:lchown",
3095 PyUnicode_FSConverter, &opath,
3096 &uid, &gid))
3097 return NULL;
3098 path = PyBytes_AsString(opath);
3099 Py_BEGIN_ALLOW_THREADS
3100 res = lchown(path, (uid_t) uid, (gid_t) gid);
3101 Py_END_ALLOW_THREADS
3102 if (res < 0)
3103 return posix_error_with_allocated_filename(opath);
3104 Py_DECREF(opath);
3105 Py_INCREF(Py_None);
3106 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003107}
3108#endif /* HAVE_LCHOWN */
3109
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003110
Guido van Rossum36bc6801995-06-14 22:54:23 +00003111#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003112static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003113posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003114{
Victor Stinner8c62be82010-05-06 00:08:46 +00003115 char buf[1026];
3116 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003117
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003118#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003119 if (!use_bytes) {
3120 wchar_t wbuf[1026];
3121 wchar_t *wbuf2 = wbuf;
3122 PyObject *resobj;
3123 DWORD len;
3124 Py_BEGIN_ALLOW_THREADS
3125 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3126 /* If the buffer is large enough, len does not include the
3127 terminating \0. If the buffer is too small, len includes
3128 the space needed for the terminator. */
3129 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3130 wbuf2 = malloc(len * sizeof(wchar_t));
3131 if (wbuf2)
3132 len = GetCurrentDirectoryW(len, wbuf2);
3133 }
3134 Py_END_ALLOW_THREADS
3135 if (!wbuf2) {
3136 PyErr_NoMemory();
3137 return NULL;
3138 }
3139 if (!len) {
3140 if (wbuf2 != wbuf) free(wbuf2);
3141 return win32_error("getcwdu", NULL);
3142 }
3143 resobj = PyUnicode_FromWideChar(wbuf2, len);
3144 if (wbuf2 != wbuf) free(wbuf2);
3145 return resobj;
3146 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003147
3148 if (win32_warn_bytes_api())
3149 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003150#endif
3151
Victor Stinner8c62be82010-05-06 00:08:46 +00003152 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003153#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003154 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003155#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003157#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003158 Py_END_ALLOW_THREADS
3159 if (res == NULL)
3160 return posix_error();
3161 if (use_bytes)
3162 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003163 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003164}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003165
3166PyDoc_STRVAR(posix_getcwd__doc__,
3167"getcwd() -> path\n\n\
3168Return a unicode string representing the current working directory.");
3169
3170static PyObject *
3171posix_getcwd_unicode(PyObject *self)
3172{
3173 return posix_getcwd(0);
3174}
3175
3176PyDoc_STRVAR(posix_getcwdb__doc__,
3177"getcwdb() -> path\n\n\
3178Return a bytes string representing the current working directory.");
3179
3180static PyObject *
3181posix_getcwd_bytes(PyObject *self)
3182{
3183 return posix_getcwd(1);
3184}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003185#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003186
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3188#define HAVE_LINK 1
3189#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003190
Guido van Rossumb6775db1994-08-01 11:34:53 +00003191#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003192PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003193"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3194Create a hard link to a file.\n\
3195\n\
3196If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3197 descriptor open to a directory, and the respective path string (src or dst)\n\
3198 should be relative; the path will then be relative to that directory.\n\
3199If follow_symlinks is False, and the last element of src is a symbolic\n\
3200 link, link will create a link to the symbolic link itself instead of the\n\
3201 file the link points to.\n\
3202src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3203 platform. If they are unavailable, using them will raise a\n\
3204 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003205
Barry Warsaw53699e91996-12-10 23:23:01 +00003206static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003207posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003208{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003209 path_t src, dst;
3210 int src_dir_fd = DEFAULT_DIR_FD;
3211 int dst_dir_fd = DEFAULT_DIR_FD;
3212 int follow_symlinks = 1;
3213 PyObject *return_value = NULL;
3214 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3215 "follow_symlinks", NULL};
3216#ifdef MS_WINDOWS
3217 BOOL result;
3218#else
3219 int result;
3220#endif
3221
3222 memset(&src, 0, sizeof(src));
3223 memset(&dst, 0, sizeof(dst));
3224 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3225 path_converter, &src,
3226 path_converter, &dst,
3227 dir_fd_converter, &src_dir_fd,
3228 dir_fd_converter, &dst_dir_fd,
3229 &follow_symlinks))
3230 return NULL;
3231
3232#ifndef HAVE_LINKAT
3233 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3234 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3235 goto exit;
3236 }
3237#endif
3238
3239 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3240 PyErr_SetString(PyExc_NotImplementedError,
3241 "link: src and dst must be the same type");
3242 goto exit;
3243 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003244
Brian Curtin1b9df392010-11-24 20:24:31 +00003245#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003246 Py_BEGIN_ALLOW_THREADS
3247 if (src.wide)
3248 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3249 else
3250 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3251 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003252
Larry Hastings9cf065c2012-06-22 16:30:09 -07003253 if (!result) {
3254 return_value = win32_error_object("link", dst.object);
3255 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003256 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003257#else
3258 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003259#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003260 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3261 (dst_dir_fd != DEFAULT_DIR_FD) ||
3262 (!follow_symlinks))
3263 result = linkat(src_dir_fd, src.narrow,
3264 dst_dir_fd, dst.narrow,
3265 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3266 else
3267#endif
3268 result = link(src.narrow, dst.narrow);
3269 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003270
Larry Hastings9cf065c2012-06-22 16:30:09 -07003271 if (result) {
3272 return_value = path_error("link", &dst);
3273 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003274 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003275#endif
3276
3277 return_value = Py_None;
3278 Py_INCREF(Py_None);
3279
3280exit:
3281 path_cleanup(&src);
3282 path_cleanup(&dst);
3283 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003284}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003285#endif
3286
Brian Curtin1b9df392010-11-24 20:24:31 +00003287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003288
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003289PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003290"listdir(path='.') -> list_of_filenames\n\n\
3291Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003292The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003293entries '.' and '..' even if they are present in the directory.\n\
3294\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003295path can be specified as either str or bytes. If path is bytes,\n\
3296 the filenames returned will also be bytes; in all other circumstances\n\
3297 the filenames returned will be str.\n\
3298On some platforms, path may also be specified as an open file descriptor;\n\
3299 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003300 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003301
Barry Warsaw53699e91996-12-10 23:23:01 +00003302static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003303posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003304{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003305 path_t path;
3306 PyObject *list = NULL;
3307 static char *keywords[] = {"path", NULL};
3308 int fd = -1;
3309
3310#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3311 PyObject *v;
3312 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3313 BOOL result;
3314 WIN32_FIND_DATA FileData;
3315 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3316 char *bufptr = namebuf;
3317 /* only claim to have space for MAX_PATH */
3318 Py_ssize_t len = sizeof(namebuf)-5;
3319 PyObject *po = NULL;
3320 wchar_t *wnamebuf = NULL;
3321#elif defined(PYOS_OS2)
3322#ifndef MAX_PATH
3323#define MAX_PATH CCHMAXPATH
3324#endif
3325 char *pt;
3326 PyObject *v;
3327 char namebuf[MAX_PATH+5];
3328 HDIR hdir = 1;
3329 ULONG srchcnt = 1;
3330 FILEFINDBUF3 ep;
3331 APIRET rc;
3332#else
3333 PyObject *v;
3334 DIR *dirp = NULL;
3335 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003336 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003337#endif
3338
3339 memset(&path, 0, sizeof(path));
3340 path.nullable = 1;
3341#ifdef HAVE_FDOPENDIR
3342 path.allow_fd = 1;
3343 path.fd = -1;
3344#endif
3345 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3346 path_converter, &path
3347 ))
3348 return NULL;
3349
Victor Stinner8c62be82010-05-06 00:08:46 +00003350 /* XXX Should redo this putting the (now four) versions of opendir
3351 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003352#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003353 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003355 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003356
Larry Hastings9cf065c2012-06-22 16:30:09 -07003357 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003358 po_wchars = L".";
3359 len = 1;
3360 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003361 po_wchars = path.wide;
3362 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003363 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003365 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3366 if (!wnamebuf) {
3367 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003369 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003370 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003371 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003372 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003373 if (wch != L'/' && wch != L'\\' && wch != L':')
3374 wnamebuf[len++] = L'\\';
3375 wcscpy(wnamebuf + len, L"*.*");
3376 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003377 if ((list = PyList_New(0)) == NULL) {
3378 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003379 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003380 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003381 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003382 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003383 if (hFindFile == INVALID_HANDLE_VALUE) {
3384 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003385 if (error == ERROR_FILE_NOT_FOUND)
3386 goto exit;
3387 Py_DECREF(list);
3388 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003389 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003390 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003391 }
3392 do {
3393 /* Skip over . and .. */
3394 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3395 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003396 v = PyUnicode_FromWideChar(wFileData.cFileName,
3397 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003398 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003399 Py_DECREF(list);
3400 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003401 break;
3402 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003404 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003405 Py_DECREF(list);
3406 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 break;
3408 }
3409 Py_DECREF(v);
3410 }
3411 Py_BEGIN_ALLOW_THREADS
3412 result = FindNextFileW(hFindFile, &wFileData);
3413 Py_END_ALLOW_THREADS
3414 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3415 it got to the end of the directory. */
3416 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417 Py_DECREF(list);
3418 list = win32_error_unicode("FindNextFileW", wnamebuf);
3419 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 }
3421 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003422
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003424 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 strcpy(namebuf, path.narrow);
3426 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003427 if (len > 0) {
3428 char ch = namebuf[len-1];
3429 if (ch != SEP && ch != ALTSEP && ch != ':')
3430 namebuf[len++] = '/';
3431 strcpy(namebuf + len, "*.*");
3432 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003433
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003435 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003436
Antoine Pitroub73caab2010-08-09 23:39:31 +00003437 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003438 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003439 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 if (hFindFile == INVALID_HANDLE_VALUE) {
3441 int error = GetLastError();
3442 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 goto exit;
3444 Py_DECREF(list);
3445 list = win32_error("FindFirstFile", namebuf);
3446 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003447 }
3448 do {
3449 /* Skip over . and .. */
3450 if (strcmp(FileData.cFileName, ".") != 0 &&
3451 strcmp(FileData.cFileName, "..") != 0) {
3452 v = PyBytes_FromString(FileData.cFileName);
3453 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454 Py_DECREF(list);
3455 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 break;
3457 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003459 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003460 Py_DECREF(list);
3461 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003462 break;
3463 }
3464 Py_DECREF(v);
3465 }
3466 Py_BEGIN_ALLOW_THREADS
3467 result = FindNextFile(hFindFile, &FileData);
3468 Py_END_ALLOW_THREADS
3469 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3470 it got to the end of the directory. */
3471 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472 Py_DECREF(list);
3473 list = win32_error("FindNextFile", namebuf);
3474 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003475 }
3476 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003477
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478exit:
3479 if (hFindFile != INVALID_HANDLE_VALUE) {
3480 if (FindClose(hFindFile) == FALSE) {
3481 if (list != NULL) {
3482 Py_DECREF(list);
3483 list = win32_error_object("FindClose", path.object);
3484 }
3485 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 if (wnamebuf)
3488 free(wnamebuf);
3489 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003490
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003492
Tim Peters0bb44a42000-09-15 07:44:49 +00003493#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003494 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003495 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003497 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003499 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003500 if (*pt == ALTSEP)
3501 *pt = SEP;
3502 if (namebuf[len-1] != SEP)
3503 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003504 strcpy(namebuf + len, "*.*");
3505
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 if ((list = PyList_New(0)) == NULL) {
3507 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003508 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003509
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003510 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3511 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003512 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003513 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3514 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3515 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003516
3517 if (rc != NO_ERROR) {
3518 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 Py_DECREF(list);
3520 list = posix_error_with_filename(path.narrow);
3521 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003522 }
3523
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003524 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003525 do {
3526 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003527 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003528 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003529
3530 strcpy(namebuf, ep.achName);
3531
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003532 /* Leave Case of Name Alone -- In Native Form */
3533 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003534
Christian Heimes72b710a2008-05-26 13:28:38 +00003535 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003536 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 Py_DECREF(list);
3538 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003539 break;
3540 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003541 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003542 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 Py_DECREF(list);
3544 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003545 break;
3546 }
3547 Py_DECREF(v);
3548 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3549 }
3550
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551exit:
3552 path_cleanup(&path);
3553
3554 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003555#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003556
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558#ifdef HAVE_FDOPENDIR
3559 if (path.fd != -1) {
3560 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003561 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003563 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564
3565 if (fd == -1) {
3566 list = posix_error();
3567 goto exit;
3568 }
3569
Larry Hastingsfdaea062012-06-25 04:42:23 -07003570 return_str = 1;
3571
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572 Py_BEGIN_ALLOW_THREADS
3573 dirp = fdopendir(fd);
3574 Py_END_ALLOW_THREADS
3575 }
3576 else
3577#endif
3578 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003579 char *name;
3580 if (path.narrow) {
3581 name = path.narrow;
3582 /* only return bytes if they specified a bytes object */
3583 return_str = !(PyBytes_Check(path.object));
3584 }
3585 else {
3586 name = ".";
3587 return_str = 1;
3588 }
3589
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590 Py_BEGIN_ALLOW_THREADS
3591 dirp = opendir(name);
3592 Py_END_ALLOW_THREADS
3593 }
3594
3595 if (dirp == NULL) {
3596 list = path_error("listdir", &path);
3597 goto exit;
3598 }
3599 if ((list = PyList_New(0)) == NULL) {
3600 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003601 }
3602 for (;;) {
3603 errno = 0;
3604 Py_BEGIN_ALLOW_THREADS
3605 ep = readdir(dirp);
3606 Py_END_ALLOW_THREADS
3607 if (ep == NULL) {
3608 if (errno == 0) {
3609 break;
3610 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003611 Py_DECREF(list);
3612 list = path_error("listdir", &path);
3613 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003614 }
3615 }
3616 if (ep->d_name[0] == '.' &&
3617 (NAMLEN(ep) == 1 ||
3618 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3619 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003620 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003621 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3622 else
3623 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003626 break;
3627 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003629 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003631 break;
3632 }
3633 Py_DECREF(v);
3634 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003635
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636exit:
3637 if (dirp != NULL) {
3638 Py_BEGIN_ALLOW_THREADS
3639 if (fd > -1)
3640 rewinddir(dirp);
3641 closedir(dirp);
3642 Py_END_ALLOW_THREADS
3643 }
3644
3645 path_cleanup(&path);
3646
3647 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003648
Tim Peters0bb44a42000-09-15 07:44:49 +00003649#endif /* which OS */
3650} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003651
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003652#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003653/* A helper function for abspath on win32 */
3654static PyObject *
3655posix__getfullpathname(PyObject *self, PyObject *args)
3656{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003657 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 char outbuf[MAX_PATH*2];
3659 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003660 PyObject *po;
3661
3662 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3663 {
3664 wchar_t *wpath;
3665 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3666 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003667 DWORD result;
3668 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003669
3670 wpath = PyUnicode_AsUnicode(po);
3671 if (wpath == NULL)
3672 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003673 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003674 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003675 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003676 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003677 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003678 if (!woutbufp)
3679 return PyErr_NoMemory();
3680 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3681 }
3682 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003683 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003685 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003686 if (woutbufp != woutbuf)
3687 free(woutbufp);
3688 return v;
3689 }
3690 /* Drop the argument parsing error as narrow strings
3691 are also valid. */
3692 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003693
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003694 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3695 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003697 if (win32_warn_bytes_api())
3698 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003699 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 outbuf, &temp)) {
3701 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003702 return NULL;
3703 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003704 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3705 return PyUnicode_Decode(outbuf, strlen(outbuf),
3706 Py_FileSystemDefaultEncoding, NULL);
3707 }
3708 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003709} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003710
Brian Curtind25aef52011-06-13 15:16:04 -05003711
Brian Curtinf5e76d02010-11-24 13:14:05 +00003712
Brian Curtind40e6f72010-07-08 21:39:08 +00003713/* A helper function for samepath on windows */
3714static PyObject *
3715posix__getfinalpathname(PyObject *self, PyObject *args)
3716{
3717 HANDLE hFile;
3718 int buf_size;
3719 wchar_t *target_path;
3720 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003721 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003722 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003723
Victor Stinnereb5657a2011-09-30 01:44:27 +02003724 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003725 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003726 path = PyUnicode_AsUnicode(po);
3727 if (path == NULL)
3728 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003729
3730 if(!check_GetFinalPathNameByHandle()) {
3731 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3732 NotImplementedError. */
3733 return PyErr_Format(PyExc_NotImplementedError,
3734 "GetFinalPathNameByHandle not available on this platform");
3735 }
3736
3737 hFile = CreateFileW(
3738 path,
3739 0, /* desired access */
3740 0, /* share mode */
3741 NULL, /* security attributes */
3742 OPEN_EXISTING,
3743 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3744 FILE_FLAG_BACKUP_SEMANTICS,
3745 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003746
Victor Stinnereb5657a2011-09-30 01:44:27 +02003747 if(hFile == INVALID_HANDLE_VALUE)
3748 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003749
3750 /* We have a good handle to the target, use it to determine the
3751 target path name. */
3752 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3753
3754 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003755 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003756
3757 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3758 if(!target_path)
3759 return PyErr_NoMemory();
3760
3761 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3762 buf_size, VOLUME_NAME_DOS);
3763 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003764 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003765
3766 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003767 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003768
3769 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003770 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003771 free(target_path);
3772 return result;
3773
3774} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003775
3776static PyObject *
3777posix__getfileinformation(PyObject *self, PyObject *args)
3778{
3779 HANDLE hFile;
3780 BY_HANDLE_FILE_INFORMATION info;
3781 int fd;
3782
3783 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3784 return NULL;
3785
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003786 if (!_PyVerify_fd(fd))
3787 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003788
3789 hFile = (HANDLE)_get_osfhandle(fd);
3790 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003791 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003792
3793 if (!GetFileInformationByHandle(hFile, &info))
3794 return win32_error("_getfileinformation", NULL);
3795
3796 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3797 info.nFileIndexHigh,
3798 info.nFileIndexLow);
3799}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003800
Brian Curtin95d028f2011-06-09 09:10:38 -05003801PyDoc_STRVAR(posix__isdir__doc__,
3802"Return true if the pathname refers to an existing directory.");
3803
Brian Curtin9c669cc2011-06-08 18:17:18 -05003804static PyObject *
3805posix__isdir(PyObject *self, PyObject *args)
3806{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003807 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003808 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003809 DWORD attributes;
3810
3811 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003812 wchar_t *wpath = PyUnicode_AsUnicode(po);
3813 if (wpath == NULL)
3814 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003815
3816 attributes = GetFileAttributesW(wpath);
3817 if (attributes == INVALID_FILE_ATTRIBUTES)
3818 Py_RETURN_FALSE;
3819 goto check;
3820 }
3821 /* Drop the argument parsing error as narrow strings
3822 are also valid. */
3823 PyErr_Clear();
3824
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003825 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003826 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003827 if (win32_warn_bytes_api())
3828 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003829 attributes = GetFileAttributesA(path);
3830 if (attributes == INVALID_FILE_ATTRIBUTES)
3831 Py_RETURN_FALSE;
3832
3833check:
3834 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3835 Py_RETURN_TRUE;
3836 else
3837 Py_RETURN_FALSE;
3838}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003839#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003840
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003841PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003842"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3843Create a directory.\n\
3844\n\
3845If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3846 and path should be relative; path will then be relative to that directory.\n\
3847dir_fd may not be implemented on your platform.\n\
3848 If it is unavailable, using it will raise a NotImplementedError.\n\
3849\n\
3850The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003851
Barry Warsaw53699e91996-12-10 23:23:01 +00003852static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003853posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003854{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003855 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003856 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003857 int dir_fd = DEFAULT_DIR_FD;
3858 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3859 PyObject *return_value = NULL;
3860 int result;
3861
3862 memset(&path, 0, sizeof(path));
3863 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3864 path_converter, &path, &mode,
3865#ifdef HAVE_MKDIRAT
3866 dir_fd_converter, &dir_fd
3867#else
3868 dir_fd_unavailable, &dir_fd
3869#endif
3870 ))
3871 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003872
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003873#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003875 if (path.wide)
3876 result = CreateDirectoryW(path.wide, NULL);
3877 else
3878 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003879 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003880
Larry Hastings9cf065c2012-06-22 16:30:09 -07003881 if (!result) {
3882 return_value = win32_error_object("mkdir", path.object);
3883 goto exit;
3884 }
3885#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003886 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003887#if HAVE_MKDIRAT
3888 if (dir_fd != DEFAULT_DIR_FD)
3889 result = mkdirat(dir_fd, path.narrow, mode);
3890 else
3891#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003892#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003893 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003894#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003895 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003896#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003897 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003898 if (result < 0) {
3899 return_value = path_error("mkdir", &path);
3900 goto exit;
3901 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003902#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003903 return_value = Py_None;
3904 Py_INCREF(Py_None);
3905exit:
3906 path_cleanup(&path);
3907 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003908}
3909
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003910
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003911/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3912#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003913#include <sys/resource.h>
3914#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003915
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003916
3917#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003918PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003919"nice(inc) -> new_priority\n\n\
3920Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003921
Barry Warsaw53699e91996-12-10 23:23:01 +00003922static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003923posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003924{
Victor Stinner8c62be82010-05-06 00:08:46 +00003925 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003926
Victor Stinner8c62be82010-05-06 00:08:46 +00003927 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3928 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003929
Victor Stinner8c62be82010-05-06 00:08:46 +00003930 /* There are two flavours of 'nice': one that returns the new
3931 priority (as required by almost all standards out there) and the
3932 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3933 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003934
Victor Stinner8c62be82010-05-06 00:08:46 +00003935 If we are of the nice family that returns the new priority, we
3936 need to clear errno before the call, and check if errno is filled
3937 before calling posix_error() on a returnvalue of -1, because the
3938 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003939
Victor Stinner8c62be82010-05-06 00:08:46 +00003940 errno = 0;
3941 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003942#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003943 if (value == 0)
3944 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003945#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003946 if (value == -1 && errno != 0)
3947 /* either nice() or getpriority() returned an error */
3948 return posix_error();
3949 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003950}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003951#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003952
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003953
3954#ifdef HAVE_GETPRIORITY
3955PyDoc_STRVAR(posix_getpriority__doc__,
3956"getpriority(which, who) -> current_priority\n\n\
3957Get program scheduling priority.");
3958
3959static PyObject *
3960posix_getpriority(PyObject *self, PyObject *args)
3961{
3962 int which, who, retval;
3963
3964 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3965 return NULL;
3966 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003967 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003968 if (errno != 0)
3969 return posix_error();
3970 return PyLong_FromLong((long)retval);
3971}
3972#endif /* HAVE_GETPRIORITY */
3973
3974
3975#ifdef HAVE_SETPRIORITY
3976PyDoc_STRVAR(posix_setpriority__doc__,
3977"setpriority(which, who, prio) -> None\n\n\
3978Set program scheduling priority.");
3979
3980static PyObject *
3981posix_setpriority(PyObject *self, PyObject *args)
3982{
3983 int which, who, prio, retval;
3984
3985 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3986 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003987 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003988 if (retval == -1)
3989 return posix_error();
3990 Py_RETURN_NONE;
3991}
3992#endif /* HAVE_SETPRIORITY */
3993
3994
Barry Warsaw53699e91996-12-10 23:23:01 +00003995static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003996internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003997{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003998 char *function_name = is_replace ? "replace" : "rename";
3999 path_t src;
4000 path_t dst;
4001 int src_dir_fd = DEFAULT_DIR_FD;
4002 int dst_dir_fd = DEFAULT_DIR_FD;
4003 int dir_fd_specified;
4004 PyObject *return_value = NULL;
4005 char format[24];
4006 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4007
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004008#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004009 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004010 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004011#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004012 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004013#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004014
4015 memset(&src, 0, sizeof(src));
4016 memset(&dst, 0, sizeof(dst));
4017 strcpy(format, "O&O&|$O&O&:");
4018 strcat(format, function_name);
4019 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4020 path_converter, &src,
4021 path_converter, &dst,
4022 dir_fd_converter, &src_dir_fd,
4023 dir_fd_converter, &dst_dir_fd))
4024 return NULL;
4025
4026 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4027 (dst_dir_fd != DEFAULT_DIR_FD);
4028#ifndef HAVE_RENAMEAT
4029 if (dir_fd_specified) {
4030 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4031 goto exit;
4032 }
4033#endif
4034
4035 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4036 PyErr_Format(PyExc_ValueError,
4037 "%s: src and dst must be the same type", function_name);
4038 goto exit;
4039 }
4040
4041#ifdef MS_WINDOWS
4042 Py_BEGIN_ALLOW_THREADS
4043 if (src.wide)
4044 result = MoveFileExW(src.wide, dst.wide, flags);
4045 else
4046 result = MoveFileExA(src.narrow, dst.narrow, flags);
4047 Py_END_ALLOW_THREADS
4048
4049 if (!result) {
4050 return_value = win32_error_object(function_name, dst.object);
4051 goto exit;
4052 }
4053
4054#else
4055 Py_BEGIN_ALLOW_THREADS
4056#ifdef HAVE_RENAMEAT
4057 if (dir_fd_specified)
4058 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4059 else
4060#endif
4061 result = rename(src.narrow, dst.narrow);
4062 Py_END_ALLOW_THREADS
4063
4064 if (result) {
4065 return_value = path_error(function_name, &dst);
4066 goto exit;
4067 }
4068#endif
4069
4070 Py_INCREF(Py_None);
4071 return_value = Py_None;
4072exit:
4073 path_cleanup(&src);
4074 path_cleanup(&dst);
4075 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004076}
4077
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004078PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004079"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4080Rename a file or directory.\n\
4081\n\
4082If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4083 descriptor open to a directory, and the respective path string (src or dst)\n\
4084 should be relative; the path will then be relative to that directory.\n\
4085src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4086 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004087
4088static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004089posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004090{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004091 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004092}
4093
4094PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004095"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4096Rename a file or directory, overwriting the destination.\n\
4097\n\
4098If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4099 descriptor open to a directory, and the respective path string (src or dst)\n\
4100 should be relative; the path will then be relative to that directory.\n\
4101src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4102 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004103
4104static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004105posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004106{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004107 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004108}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004109
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004110PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004111"rmdir(path, *, dir_fd=None)\n\n\
4112Remove a directory.\n\
4113\n\
4114If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4115 and path should be relative; path will then be relative to that directory.\n\
4116dir_fd may not be implemented on your platform.\n\
4117 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004118
Barry Warsaw53699e91996-12-10 23:23:01 +00004119static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004120posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004121{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004122 path_t path;
4123 int dir_fd = DEFAULT_DIR_FD;
4124 static char *keywords[] = {"path", "dir_fd", NULL};
4125 int result;
4126 PyObject *return_value = NULL;
4127
4128 memset(&path, 0, sizeof(path));
4129 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4130 path_converter, &path,
4131#ifdef HAVE_UNLINKAT
4132 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004133#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004134 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004135#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004136 ))
4137 return NULL;
4138
4139 Py_BEGIN_ALLOW_THREADS
4140#ifdef MS_WINDOWS
4141 if (path.wide)
4142 result = RemoveDirectoryW(path.wide);
4143 else
4144 result = RemoveDirectoryA(path.narrow);
4145 result = !result; /* Windows, success=1, UNIX, success=0 */
4146#else
4147#ifdef HAVE_UNLINKAT
4148 if (dir_fd != DEFAULT_DIR_FD)
4149 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4150 else
4151#endif
4152 result = rmdir(path.narrow);
4153#endif
4154 Py_END_ALLOW_THREADS
4155
4156 if (result) {
4157 return_value = path_error("rmdir", &path);
4158 goto exit;
4159 }
4160
4161 return_value = Py_None;
4162 Py_INCREF(Py_None);
4163
4164exit:
4165 path_cleanup(&path);
4166 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004167}
4168
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004169
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004170#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004171PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004172"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004173Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004174
Barry Warsaw53699e91996-12-10 23:23:01 +00004175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004176posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004177{
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004179#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004180 wchar_t *command;
4181 if (!PyArg_ParseTuple(args, "u:system", &command))
4182 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004183
Victor Stinner8c62be82010-05-06 00:08:46 +00004184 Py_BEGIN_ALLOW_THREADS
4185 sts = _wsystem(command);
4186 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004187#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 PyObject *command_obj;
4189 char *command;
4190 if (!PyArg_ParseTuple(args, "O&:system",
4191 PyUnicode_FSConverter, &command_obj))
4192 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004193
Victor Stinner8c62be82010-05-06 00:08:46 +00004194 command = PyBytes_AsString(command_obj);
4195 Py_BEGIN_ALLOW_THREADS
4196 sts = system(command);
4197 Py_END_ALLOW_THREADS
4198 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004199#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004200 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004201}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004202#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004204
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004205PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004206"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004207Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004208
Barry Warsaw53699e91996-12-10 23:23:01 +00004209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004210posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004211{
Victor Stinner8c62be82010-05-06 00:08:46 +00004212 int i;
4213 if (!PyArg_ParseTuple(args, "i:umask", &i))
4214 return NULL;
4215 i = (int)umask(i);
4216 if (i < 0)
4217 return posix_error();
4218 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004219}
4220
Brian Curtind40e6f72010-07-08 21:39:08 +00004221#ifdef MS_WINDOWS
4222
4223/* override the default DeleteFileW behavior so that directory
4224symlinks can be removed with this function, the same as with
4225Unix symlinks */
4226BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4227{
4228 WIN32_FILE_ATTRIBUTE_DATA info;
4229 WIN32_FIND_DATAW find_data;
4230 HANDLE find_data_handle;
4231 int is_directory = 0;
4232 int is_link = 0;
4233
4234 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4235 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004236
Brian Curtind40e6f72010-07-08 21:39:08 +00004237 /* Get WIN32_FIND_DATA structure for the path to determine if
4238 it is a symlink */
4239 if(is_directory &&
4240 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4241 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4242
4243 if(find_data_handle != INVALID_HANDLE_VALUE) {
4244 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4245 FindClose(find_data_handle);
4246 }
4247 }
4248 }
4249
4250 if (is_directory && is_link)
4251 return RemoveDirectoryW(lpFileName);
4252
4253 return DeleteFileW(lpFileName);
4254}
4255#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004256
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004257PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004258"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004259Remove a file (same as remove()).\n\
4260\n\
4261If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4262 and path should be relative; path will then be relative to that directory.\n\
4263dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004264 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004265
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004266PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004267"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004268Remove a file (same as unlink()).\n\
4269\n\
4270If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4271 and path should be relative; path will then be relative to that directory.\n\
4272dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004273 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004274
Barry Warsaw53699e91996-12-10 23:23:01 +00004275static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004276posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004277{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004278 path_t path;
4279 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004280 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004281 int result;
4282 PyObject *return_value = NULL;
4283
4284 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004285 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004286 path_converter, &path,
4287#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004288 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004289#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004290 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004291#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004292 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004293 return NULL;
4294
4295 Py_BEGIN_ALLOW_THREADS
4296#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004297 if (path.wide)
4298 result = Py_DeleteFileW(path.wide);
4299 else
4300 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004301 result = !result; /* Windows, success=1, UNIX, success=0 */
4302#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004303#ifdef HAVE_UNLINKAT
4304 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004305 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004306 else
4307#endif /* HAVE_UNLINKAT */
4308 result = unlink(path.narrow);
4309#endif
4310 Py_END_ALLOW_THREADS
4311
4312 if (result) {
4313 return_value = path_error("unlink", &path);
4314 goto exit;
4315 }
4316
4317 return_value = Py_None;
4318 Py_INCREF(Py_None);
4319
4320exit:
4321 path_cleanup(&path);
4322 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004323}
4324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004325
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004326PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004327"uname() -> uname_result\n\n\
4328Return an object identifying the current operating system.\n\
4329The object behaves like a named tuple with the following fields:\n\
4330 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004331
Larry Hastings605a62d2012-06-24 04:33:36 -07004332static PyStructSequence_Field uname_result_fields[] = {
4333 {"sysname", "operating system name"},
4334 {"nodename", "name of machine on network (implementation-defined)"},
4335 {"release", "operating system release"},
4336 {"version", "operating system version"},
4337 {"machine", "hardware identifier"},
4338 {NULL}
4339};
4340
4341PyDoc_STRVAR(uname_result__doc__,
4342"uname_result: Result from os.uname().\n\n\
4343This object may be accessed either as a tuple of\n\
4344 (sysname, nodename, release, version, machine),\n\
4345or via the attributes sysname, nodename, release, version, and machine.\n\
4346\n\
4347See os.uname for more information.");
4348
4349static PyStructSequence_Desc uname_result_desc = {
4350 "uname_result", /* name */
4351 uname_result__doc__, /* doc */
4352 uname_result_fields,
4353 5
4354};
4355
4356static PyTypeObject UnameResultType;
4357
4358
4359#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004360static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004361posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004362{
Victor Stinner8c62be82010-05-06 00:08:46 +00004363 struct utsname u;
4364 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004365 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004366
Victor Stinner8c62be82010-05-06 00:08:46 +00004367 Py_BEGIN_ALLOW_THREADS
4368 res = uname(&u);
4369 Py_END_ALLOW_THREADS
4370 if (res < 0)
4371 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004372
4373 value = PyStructSequence_New(&UnameResultType);
4374 if (value == NULL)
4375 return NULL;
4376
4377#define SET(i, field) \
4378 { \
4379 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4380 if (!o) { \
4381 Py_DECREF(value); \
4382 return NULL; \
4383 } \
4384 PyStructSequence_SET_ITEM(value, i, o); \
4385 } \
4386
4387 SET(0, u.sysname);
4388 SET(1, u.nodename);
4389 SET(2, u.release);
4390 SET(3, u.version);
4391 SET(4, u.machine);
4392
4393#undef SET
4394
4395 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004396}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004397#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004398
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004399
Larry Hastings9cf065c2012-06-22 16:30:09 -07004400PyDoc_STRVAR(posix_utime__doc__,
4401"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4402Set the access and modified time of path.\n\
4403\n\
4404path may always be specified as a string.\n\
4405On some platforms, path may also be specified as an open file descriptor.\n\
4406 If this functionality is unavailable, using it raises an exception.\n\
4407\n\
4408If times is not None, it must be a tuple (atime, mtime);\n\
4409 atime and mtime should be expressed as float seconds since the epoch.\n\
4410If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4411 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4412 since the epoch.\n\
4413If both times and ns are None, utime uses the current time.\n\
4414Specifying tuples for both times and ns is an error.\n\
4415\n\
4416If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4417 and path should be relative; path will then be relative to that directory.\n\
4418If follow_symlinks is False, and the last element of the path is a symbolic\n\
4419 link, utime will modify the symbolic link itself instead of the file the\n\
4420 link points to.\n\
4421It is an error to use dir_fd or follow_symlinks when specifying path\n\
4422 as an open file descriptor.\n\
4423dir_fd and follow_symlinks may not be available on your platform.\n\
4424 If they are unavailable, using them will raise a NotImplementedError.");
4425
4426typedef struct {
4427 int now;
4428 time_t atime_s;
4429 long atime_ns;
4430 time_t mtime_s;
4431 long mtime_ns;
4432} utime_t;
4433
4434/*
4435 * these macros assume that "utime" is a pointer to a utime_t
4436 * they also intentionally leak the declaration of a pointer named "time"
4437 */
4438#define UTIME_TO_TIMESPEC \
4439 struct timespec ts[2]; \
4440 struct timespec *time; \
4441 if (utime->now) \
4442 time = NULL; \
4443 else { \
4444 ts[0].tv_sec = utime->atime_s; \
4445 ts[0].tv_nsec = utime->atime_ns; \
4446 ts[1].tv_sec = utime->mtime_s; \
4447 ts[1].tv_nsec = utime->mtime_ns; \
4448 time = ts; \
4449 } \
4450
4451#define UTIME_TO_TIMEVAL \
4452 struct timeval tv[2]; \
4453 struct timeval *time; \
4454 if (utime->now) \
4455 time = NULL; \
4456 else { \
4457 tv[0].tv_sec = utime->atime_s; \
4458 tv[0].tv_usec = utime->atime_ns / 1000; \
4459 tv[1].tv_sec = utime->mtime_s; \
4460 tv[1].tv_usec = utime->mtime_ns / 1000; \
4461 time = tv; \
4462 } \
4463
4464#define UTIME_TO_UTIMBUF \
4465 struct utimbuf u[2]; \
4466 struct utimbuf *time; \
4467 if (utime->now) \
4468 time = NULL; \
4469 else { \
4470 u.actime = utime->atime_s; \
4471 u.modtime = utime->mtime_s; \
4472 time = u; \
4473 }
4474
4475#define UTIME_TO_TIME_T \
4476 time_t timet[2]; \
4477 struct timet time; \
4478 if (utime->now) \
4479 time = NULL; \
4480 else { \
4481 timet[0] = utime->atime_s; \
4482 timet[1] = utime->mtime_s; \
4483 time = &timet; \
4484 } \
4485
4486
4487#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4488
4489#if UTIME_HAVE_DIR_FD
4490
4491static int
4492utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4493{
4494#ifdef HAVE_UTIMENSAT
4495 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4496 UTIME_TO_TIMESPEC;
4497 return utimensat(dir_fd, path, time, flags);
4498#elif defined(HAVE_FUTIMESAT)
4499 UTIME_TO_TIMEVAL;
4500 /*
4501 * follow_symlinks will never be false here;
4502 * we only allow !follow_symlinks and dir_fd together
4503 * if we have utimensat()
4504 */
4505 assert(follow_symlinks);
4506 return futimesat(dir_fd, path, time);
4507#endif
4508}
4509
4510#endif
4511
4512#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4513
4514#if UTIME_HAVE_FD
4515
4516static int
4517utime_fd(utime_t *utime, int fd)
4518{
4519#ifdef HAVE_FUTIMENS
4520 UTIME_TO_TIMESPEC;
4521 return futimens(fd, time);
4522#else
4523 UTIME_TO_TIMEVAL;
4524 return futimes(fd, time);
4525#endif
4526}
4527
4528#endif
4529
4530
4531#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4532 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4533
4534#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4535
4536static int
4537utime_nofollow_symlinks(utime_t *utime, char *path)
4538{
4539#ifdef HAVE_UTIMENSAT
4540 UTIME_TO_TIMESPEC;
4541 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4542#else
4543 UTIME_TO_TIMEVAL;
4544 return lutimes(path, time);
4545#endif
4546}
4547
4548#endif
4549
4550#ifndef MS_WINDOWS
4551
4552static int
4553utime_default(utime_t *utime, char *path)
4554{
4555#ifdef HAVE_UTIMENSAT
4556 UTIME_TO_TIMESPEC;
4557 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4558#elif defined(HAVE_UTIMES)
4559 UTIME_TO_TIMEVAL;
4560 return utimes(path, time);
4561#elif defined(HAVE_UTIME_H)
4562 UTIME_TO_UTIMBUF;
4563 return utime(path, time);
4564#else
4565 UTIME_TO_TIME_T;
4566 return utime(path, time);
4567#endif
4568}
4569
4570#endif
4571
Larry Hastings76ad59b2012-05-03 00:30:07 -07004572static int
4573split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4574{
4575 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004576 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004577 divmod = PyNumber_Divmod(py_long, billion);
4578 if (!divmod)
4579 goto exit;
4580 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4581 if ((*s == -1) && PyErr_Occurred())
4582 goto exit;
4583 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004584 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004585 goto exit;
4586
4587 result = 1;
4588exit:
4589 Py_XDECREF(divmod);
4590 return result;
4591}
4592
Larry Hastings9cf065c2012-06-22 16:30:09 -07004593static PyObject *
4594posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004595{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004596 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004597 PyObject *times = NULL;
4598 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004599 int dir_fd = DEFAULT_DIR_FD;
4600 int follow_symlinks = 1;
4601 char *keywords[] = {"path", "times", "ns", "dir_fd",
4602 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004603
Larry Hastings9cf065c2012-06-22 16:30:09 -07004604 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004605
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606#ifdef MS_WINDOWS
4607 HANDLE hFile;
4608 FILETIME atime, mtime;
4609#else
4610 int result;
4611#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004612
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004614
Larry Hastings9cf065c2012-06-22 16:30:09 -07004615 memset(&path, 0, sizeof(path));
4616#if UTIME_HAVE_FD
4617 path.allow_fd = 1;
4618#endif
4619 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4620 "O&|O$OO&p:utime", keywords,
4621 path_converter, &path,
4622 &times, &ns,
4623#if UTIME_HAVE_DIR_FD
4624 dir_fd_converter, &dir_fd,
4625#else
4626 dir_fd_unavailable, &dir_fd,
4627#endif
4628 &follow_symlinks
4629 ))
4630 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004631
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632 if (times && (times != Py_None) && ns) {
4633 PyErr_SetString(PyExc_ValueError,
4634 "utime: you may specify either 'times'"
4635 " or 'ns' but not both");
4636 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004637 }
4638
4639 if (times && (times != Py_None)) {
4640 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641 PyErr_SetString(PyExc_TypeError,
4642 "utime: 'times' must be either"
4643 " a tuple of two ints or None");
4644 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004645 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004647 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004648 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004649 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004650 &utime.mtime_s, &utime.mtime_ns) == -1) {
4651 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004652 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004653 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004654 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004655 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004656 PyErr_SetString(PyExc_TypeError,
4657 "utime: 'ns' must be a tuple of two ints");
4658 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004659 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004660 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004661 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004662 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004663 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004664 &utime.mtime_s, &utime.mtime_ns)) {
4665 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004666 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004667 }
4668 else {
4669 /* times and ns are both None/unspecified. use "now". */
4670 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004671 }
4672
Larry Hastings9cf065c2012-06-22 16:30:09 -07004673#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4674 if (follow_symlinks_specified("utime", follow_symlinks))
4675 goto exit;
4676#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004677
Larry Hastings9cf065c2012-06-22 16:30:09 -07004678 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4679 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4680 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4681 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004682
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683#if !defined(HAVE_UTIMENSAT)
4684 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004685 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 "utime: cannot use dir_fd and follow_symlinks "
4687 "together on this platform");
4688 goto exit;
4689 }
4690#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004691
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004692#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693 Py_BEGIN_ALLOW_THREADS
4694 if (path.wide)
4695 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004696 NULL, OPEN_EXISTING,
4697 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004698 else
4699 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004700 NULL, OPEN_EXISTING,
4701 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702 Py_END_ALLOW_THREADS
4703 if (hFile == INVALID_HANDLE_VALUE) {
4704 win32_error_object("utime", path.object);
4705 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004706 }
4707
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004709 SYSTEMTIME now;
4710 GetSystemTime(&now);
4711 if (!SystemTimeToFileTime(&now, &mtime) ||
4712 !SystemTimeToFileTime(&now, &atime)) {
4713 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004714 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004715 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004716 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004717 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004718 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4719 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004720 }
4721 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4722 /* Avoid putting the file name into the error here,
4723 as that may confuse the user into believing that
4724 something is wrong with the file, when it also
4725 could be the time stamp that gives a problem. */
4726 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004728 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004729#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004730 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004731
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4733 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4734 result = utime_nofollow_symlinks(&utime, path.narrow);
4735 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004736#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737
4738#if UTIME_HAVE_DIR_FD
4739 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4740 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4741 else
4742#endif
4743
4744#if UTIME_HAVE_FD
4745 if (path.fd != -1)
4746 result = utime_fd(&utime, path.fd);
4747 else
4748#endif
4749
4750 result = utime_default(&utime, path.narrow);
4751
4752 Py_END_ALLOW_THREADS
4753
4754 if (result < 0) {
4755 /* see previous comment about not putting filename in error here */
4756 return_value = posix_error();
4757 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004758 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004759
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004760#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761
4762 Py_INCREF(Py_None);
4763 return_value = Py_None;
4764
4765exit:
4766 path_cleanup(&path);
4767#ifdef MS_WINDOWS
4768 if (hFile != INVALID_HANDLE_VALUE)
4769 CloseHandle(hFile);
4770#endif
4771 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004772}
4773
Guido van Rossum3b066191991-06-04 19:40:25 +00004774/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004775
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004776PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004777"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004778Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004779
Barry Warsaw53699e91996-12-10 23:23:01 +00004780static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004781posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004782{
Victor Stinner8c62be82010-05-06 00:08:46 +00004783 int sts;
4784 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4785 return NULL;
4786 _exit(sts);
4787 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004788}
4789
Martin v. Löwis114619e2002-10-07 06:44:21 +00004790#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4791static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004792free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004793{
Victor Stinner8c62be82010-05-06 00:08:46 +00004794 Py_ssize_t i;
4795 for (i = 0; i < count; i++)
4796 PyMem_Free(array[i]);
4797 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004798}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004799
Antoine Pitrou69f71142009-05-24 21:25:49 +00004800static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004801int fsconvert_strdup(PyObject *o, char**out)
4802{
Victor Stinner8c62be82010-05-06 00:08:46 +00004803 PyObject *bytes;
4804 Py_ssize_t size;
4805 if (!PyUnicode_FSConverter(o, &bytes))
4806 return 0;
4807 size = PyBytes_GET_SIZE(bytes);
4808 *out = PyMem_Malloc(size+1);
4809 if (!*out)
4810 return 0;
4811 memcpy(*out, PyBytes_AsString(bytes), size+1);
4812 Py_DECREF(bytes);
4813 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004814}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004815#endif
4816
Ross Lagerwall7807c352011-03-17 20:20:30 +02004817#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004818static char**
4819parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4820{
Victor Stinner8c62be82010-05-06 00:08:46 +00004821 char **envlist;
4822 Py_ssize_t i, pos, envc;
4823 PyObject *keys=NULL, *vals=NULL;
4824 PyObject *key, *val, *key2, *val2;
4825 char *p, *k, *v;
4826 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004827
Victor Stinner8c62be82010-05-06 00:08:46 +00004828 i = PyMapping_Size(env);
4829 if (i < 0)
4830 return NULL;
4831 envlist = PyMem_NEW(char *, i + 1);
4832 if (envlist == NULL) {
4833 PyErr_NoMemory();
4834 return NULL;
4835 }
4836 envc = 0;
4837 keys = PyMapping_Keys(env);
4838 vals = PyMapping_Values(env);
4839 if (!keys || !vals)
4840 goto error;
4841 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4842 PyErr_Format(PyExc_TypeError,
4843 "env.keys() or env.values() is not a list");
4844 goto error;
4845 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004846
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 for (pos = 0; pos < i; pos++) {
4848 key = PyList_GetItem(keys, pos);
4849 val = PyList_GetItem(vals, pos);
4850 if (!key || !val)
4851 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004852
Victor Stinner8c62be82010-05-06 00:08:46 +00004853 if (PyUnicode_FSConverter(key, &key2) == 0)
4854 goto error;
4855 if (PyUnicode_FSConverter(val, &val2) == 0) {
4856 Py_DECREF(key2);
4857 goto error;
4858 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004859
4860#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004861 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4862 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004863#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004864 k = PyBytes_AsString(key2);
4865 v = PyBytes_AsString(val2);
4866 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004867
Victor Stinner8c62be82010-05-06 00:08:46 +00004868 p = PyMem_NEW(char, len);
4869 if (p == NULL) {
4870 PyErr_NoMemory();
4871 Py_DECREF(key2);
4872 Py_DECREF(val2);
4873 goto error;
4874 }
4875 PyOS_snprintf(p, len, "%s=%s", k, v);
4876 envlist[envc++] = p;
4877 Py_DECREF(key2);
4878 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004879#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004880 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004881#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004882 }
4883 Py_DECREF(vals);
4884 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004885
Victor Stinner8c62be82010-05-06 00:08:46 +00004886 envlist[envc] = 0;
4887 *envc_ptr = envc;
4888 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004889
4890error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004891 Py_XDECREF(keys);
4892 Py_XDECREF(vals);
4893 while (--envc >= 0)
4894 PyMem_DEL(envlist[envc]);
4895 PyMem_DEL(envlist);
4896 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004897}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004898
Ross Lagerwall7807c352011-03-17 20:20:30 +02004899static char**
4900parse_arglist(PyObject* argv, Py_ssize_t *argc)
4901{
4902 int i;
4903 char **argvlist = PyMem_NEW(char *, *argc+1);
4904 if (argvlist == NULL) {
4905 PyErr_NoMemory();
4906 return NULL;
4907 }
4908 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004909 PyObject* item = PySequence_ITEM(argv, i);
4910 if (item == NULL)
4911 goto fail;
4912 if (!fsconvert_strdup(item, &argvlist[i])) {
4913 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004914 goto fail;
4915 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004916 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004917 }
4918 argvlist[*argc] = NULL;
4919 return argvlist;
4920fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004921 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004922 free_string_array(argvlist, *argc);
4923 return NULL;
4924}
4925#endif
4926
4927#ifdef HAVE_EXECV
4928PyDoc_STRVAR(posix_execv__doc__,
4929"execv(path, args)\n\n\
4930Execute an executable path with arguments, replacing current process.\n\
4931\n\
4932 path: path of executable file\n\
4933 args: tuple or list of strings");
4934
4935static PyObject *
4936posix_execv(PyObject *self, PyObject *args)
4937{
4938 PyObject *opath;
4939 char *path;
4940 PyObject *argv;
4941 char **argvlist;
4942 Py_ssize_t argc;
4943
4944 /* execv has two arguments: (path, argv), where
4945 argv is a list or tuple of strings. */
4946
4947 if (!PyArg_ParseTuple(args, "O&O:execv",
4948 PyUnicode_FSConverter,
4949 &opath, &argv))
4950 return NULL;
4951 path = PyBytes_AsString(opath);
4952 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4953 PyErr_SetString(PyExc_TypeError,
4954 "execv() arg 2 must be a tuple or list");
4955 Py_DECREF(opath);
4956 return NULL;
4957 }
4958 argc = PySequence_Size(argv);
4959 if (argc < 1) {
4960 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4961 Py_DECREF(opath);
4962 return NULL;
4963 }
4964
4965 argvlist = parse_arglist(argv, &argc);
4966 if (argvlist == NULL) {
4967 Py_DECREF(opath);
4968 return NULL;
4969 }
4970
4971 execv(path, argvlist);
4972
4973 /* If we get here it's definitely an error */
4974
4975 free_string_array(argvlist, argc);
4976 Py_DECREF(opath);
4977 return posix_error();
4978}
4979
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004980PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004981"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004982Execute a path with arguments and environment, replacing current process.\n\
4983\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 path: path of executable file\n\
4985 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004986 env: dictionary of strings mapping to strings\n\
4987\n\
4988On some platforms, you may specify an open file descriptor for path;\n\
4989 execve will execute the program the file descriptor is open to.\n\
4990 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004991
Barry Warsaw53699e91996-12-10 23:23:01 +00004992static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004993posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004994{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004995 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004997 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004998 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004999 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005000 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005001
Victor Stinner8c62be82010-05-06 00:08:46 +00005002 /* execve has three arguments: (path, argv, env), where
5003 argv is a list or tuple of strings and env is a dictionary
5004 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005005
Larry Hastings9cf065c2012-06-22 16:30:09 -07005006 memset(&path, 0, sizeof(path));
5007#ifdef HAVE_FEXECVE
5008 path.allow_fd = 1;
5009#endif
5010 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5011 path_converter, &path,
5012 &argv, &env
5013 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005014 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005015
Ross Lagerwall7807c352011-03-17 20:20:30 +02005016 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005018 "execve: argv must be a tuple or list");
5019 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005021 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005022 if (!PyMapping_Check(env)) {
5023 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005024 "execve: environment must be a mapping object");
5025 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005026 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005027
Ross Lagerwall7807c352011-03-17 20:20:30 +02005028 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005029 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005030 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005031 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005032
Victor Stinner8c62be82010-05-06 00:08:46 +00005033 envlist = parse_envlist(env, &envc);
5034 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005035 goto fail;
5036
Larry Hastings9cf065c2012-06-22 16:30:09 -07005037#ifdef HAVE_FEXECVE
5038 if (path.fd > -1)
5039 fexecve(path.fd, argvlist, envlist);
5040 else
5041#endif
5042 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005043
5044 /* If we get here it's definitely an error */
5045
Larry Hastings9cf065c2012-06-22 16:30:09 -07005046 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005047
5048 while (--envc >= 0)
5049 PyMem_DEL(envlist[envc]);
5050 PyMem_DEL(envlist);
5051 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005052 if (argvlist)
5053 free_string_array(argvlist, argc);
5054 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005055 return NULL;
5056}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005057#endif /* HAVE_EXECV */
5058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005059
Guido van Rossuma1065681999-01-25 23:20:23 +00005060#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005061PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005062"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005063Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005064\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005065 mode: mode of process creation\n\
5066 path: path of executable file\n\
5067 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005068
5069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005070posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005071{
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 PyObject *opath;
5073 char *path;
5074 PyObject *argv;
5075 char **argvlist;
5076 int mode, i;
5077 Py_ssize_t argc;
5078 Py_intptr_t spawnval;
5079 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005080
Victor Stinner8c62be82010-05-06 00:08:46 +00005081 /* spawnv has three arguments: (mode, path, argv), where
5082 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005083
Victor Stinner8c62be82010-05-06 00:08:46 +00005084 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5085 PyUnicode_FSConverter,
5086 &opath, &argv))
5087 return NULL;
5088 path = PyBytes_AsString(opath);
5089 if (PyList_Check(argv)) {
5090 argc = PyList_Size(argv);
5091 getitem = PyList_GetItem;
5092 }
5093 else if (PyTuple_Check(argv)) {
5094 argc = PyTuple_Size(argv);
5095 getitem = PyTuple_GetItem;
5096 }
5097 else {
5098 PyErr_SetString(PyExc_TypeError,
5099 "spawnv() arg 2 must be a tuple or list");
5100 Py_DECREF(opath);
5101 return NULL;
5102 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005103
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 argvlist = PyMem_NEW(char *, argc+1);
5105 if (argvlist == NULL) {
5106 Py_DECREF(opath);
5107 return PyErr_NoMemory();
5108 }
5109 for (i = 0; i < argc; i++) {
5110 if (!fsconvert_strdup((*getitem)(argv, i),
5111 &argvlist[i])) {
5112 free_string_array(argvlist, i);
5113 PyErr_SetString(
5114 PyExc_TypeError,
5115 "spawnv() arg 2 must contain only strings");
5116 Py_DECREF(opath);
5117 return NULL;
5118 }
5119 }
5120 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005121
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005122#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 Py_BEGIN_ALLOW_THREADS
5124 spawnval = spawnv(mode, path, argvlist);
5125 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005126#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005127 if (mode == _OLD_P_OVERLAY)
5128 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005129
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 Py_BEGIN_ALLOW_THREADS
5131 spawnval = _spawnv(mode, path, argvlist);
5132 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005133#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005134
Victor Stinner8c62be82010-05-06 00:08:46 +00005135 free_string_array(argvlist, argc);
5136 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005137
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 if (spawnval == -1)
5139 return posix_error();
5140 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005141#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005143#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005145#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005146}
5147
5148
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005149PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005150"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005151Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005152\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005153 mode: mode of process creation\n\
5154 path: path of executable file\n\
5155 args: tuple or list of arguments\n\
5156 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005157
5158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005159posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005160{
Victor Stinner8c62be82010-05-06 00:08:46 +00005161 PyObject *opath;
5162 char *path;
5163 PyObject *argv, *env;
5164 char **argvlist;
5165 char **envlist;
5166 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005167 int mode;
5168 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005169 Py_intptr_t spawnval;
5170 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5171 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005172
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 /* spawnve has four arguments: (mode, path, argv, env), where
5174 argv is a list or tuple of strings and env is a dictionary
5175 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005176
Victor Stinner8c62be82010-05-06 00:08:46 +00005177 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5178 PyUnicode_FSConverter,
5179 &opath, &argv, &env))
5180 return NULL;
5181 path = PyBytes_AsString(opath);
5182 if (PyList_Check(argv)) {
5183 argc = PyList_Size(argv);
5184 getitem = PyList_GetItem;
5185 }
5186 else if (PyTuple_Check(argv)) {
5187 argc = PyTuple_Size(argv);
5188 getitem = PyTuple_GetItem;
5189 }
5190 else {
5191 PyErr_SetString(PyExc_TypeError,
5192 "spawnve() arg 2 must be a tuple or list");
5193 goto fail_0;
5194 }
5195 if (!PyMapping_Check(env)) {
5196 PyErr_SetString(PyExc_TypeError,
5197 "spawnve() arg 3 must be a mapping object");
5198 goto fail_0;
5199 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005200
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 argvlist = PyMem_NEW(char *, argc+1);
5202 if (argvlist == NULL) {
5203 PyErr_NoMemory();
5204 goto fail_0;
5205 }
5206 for (i = 0; i < argc; i++) {
5207 if (!fsconvert_strdup((*getitem)(argv, i),
5208 &argvlist[i]))
5209 {
5210 lastarg = i;
5211 goto fail_1;
5212 }
5213 }
5214 lastarg = argc;
5215 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005216
Victor Stinner8c62be82010-05-06 00:08:46 +00005217 envlist = parse_envlist(env, &envc);
5218 if (envlist == NULL)
5219 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005220
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005221#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 Py_BEGIN_ALLOW_THREADS
5223 spawnval = spawnve(mode, path, argvlist, envlist);
5224 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005225#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 if (mode == _OLD_P_OVERLAY)
5227 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005228
Victor Stinner8c62be82010-05-06 00:08:46 +00005229 Py_BEGIN_ALLOW_THREADS
5230 spawnval = _spawnve(mode, path, argvlist, envlist);
5231 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005232#endif
Tim Peters25059d32001-12-07 20:35:43 +00005233
Victor Stinner8c62be82010-05-06 00:08:46 +00005234 if (spawnval == -1)
5235 (void) posix_error();
5236 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005237#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005238 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005239#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005241#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005242
Victor Stinner8c62be82010-05-06 00:08:46 +00005243 while (--envc >= 0)
5244 PyMem_DEL(envlist[envc]);
5245 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005246 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005247 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005248 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005249 Py_DECREF(opath);
5250 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005251}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005252
5253/* OS/2 supports spawnvp & spawnvpe natively */
5254#if defined(PYOS_OS2)
5255PyDoc_STRVAR(posix_spawnvp__doc__,
5256"spawnvp(mode, file, args)\n\n\
5257Execute the program 'file' in a new process, using the environment\n\
5258search path to find the file.\n\
5259\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 mode: mode of process creation\n\
5261 file: executable file name\n\
5262 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005263
5264static PyObject *
5265posix_spawnvp(PyObject *self, PyObject *args)
5266{
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 PyObject *opath;
5268 char *path;
5269 PyObject *argv;
5270 char **argvlist;
5271 int mode, i, argc;
5272 Py_intptr_t spawnval;
5273 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005274
Victor Stinner8c62be82010-05-06 00:08:46 +00005275 /* spawnvp has three arguments: (mode, path, argv), where
5276 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005277
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5279 PyUnicode_FSConverter,
5280 &opath, &argv))
5281 return NULL;
5282 path = PyBytes_AsString(opath);
5283 if (PyList_Check(argv)) {
5284 argc = PyList_Size(argv);
5285 getitem = PyList_GetItem;
5286 }
5287 else if (PyTuple_Check(argv)) {
5288 argc = PyTuple_Size(argv);
5289 getitem = PyTuple_GetItem;
5290 }
5291 else {
5292 PyErr_SetString(PyExc_TypeError,
5293 "spawnvp() arg 2 must be a tuple or list");
5294 Py_DECREF(opath);
5295 return NULL;
5296 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005297
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 argvlist = PyMem_NEW(char *, argc+1);
5299 if (argvlist == NULL) {
5300 Py_DECREF(opath);
5301 return PyErr_NoMemory();
5302 }
5303 for (i = 0; i < argc; i++) {
5304 if (!fsconvert_strdup((*getitem)(argv, i),
5305 &argvlist[i])) {
5306 free_string_array(argvlist, i);
5307 PyErr_SetString(
5308 PyExc_TypeError,
5309 "spawnvp() arg 2 must contain only strings");
5310 Py_DECREF(opath);
5311 return NULL;
5312 }
5313 }
5314 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005315
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005317#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005318 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005319#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005320 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005321#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005322 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005323
Victor Stinner8c62be82010-05-06 00:08:46 +00005324 free_string_array(argvlist, argc);
5325 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005326
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 if (spawnval == -1)
5328 return posix_error();
5329 else
5330 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005331}
5332
5333
5334PyDoc_STRVAR(posix_spawnvpe__doc__,
5335"spawnvpe(mode, file, args, env)\n\n\
5336Execute the program 'file' in a new process, using the environment\n\
5337search path to find the file.\n\
5338\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005339 mode: mode of process creation\n\
5340 file: executable file name\n\
5341 args: tuple or list of arguments\n\
5342 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005343
5344static PyObject *
5345posix_spawnvpe(PyObject *self, PyObject *args)
5346{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005347 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 char *path;
5349 PyObject *argv, *env;
5350 char **argvlist;
5351 char **envlist;
5352 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005353 int mode;
5354 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005355 Py_intptr_t spawnval;
5356 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5357 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005358
Victor Stinner8c62be82010-05-06 00:08:46 +00005359 /* spawnvpe has four arguments: (mode, path, argv, env), where
5360 argv is a list or tuple of strings and env is a dictionary
5361 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005362
Victor Stinner8c62be82010-05-06 00:08:46 +00005363 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5364 PyUnicode_FSConverter,
5365 &opath, &argv, &env))
5366 return NULL;
5367 path = PyBytes_AsString(opath);
5368 if (PyList_Check(argv)) {
5369 argc = PyList_Size(argv);
5370 getitem = PyList_GetItem;
5371 }
5372 else if (PyTuple_Check(argv)) {
5373 argc = PyTuple_Size(argv);
5374 getitem = PyTuple_GetItem;
5375 }
5376 else {
5377 PyErr_SetString(PyExc_TypeError,
5378 "spawnvpe() arg 2 must be a tuple or list");
5379 goto fail_0;
5380 }
5381 if (!PyMapping_Check(env)) {
5382 PyErr_SetString(PyExc_TypeError,
5383 "spawnvpe() arg 3 must be a mapping object");
5384 goto fail_0;
5385 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005386
Victor Stinner8c62be82010-05-06 00:08:46 +00005387 argvlist = PyMem_NEW(char *, argc+1);
5388 if (argvlist == NULL) {
5389 PyErr_NoMemory();
5390 goto fail_0;
5391 }
5392 for (i = 0; i < argc; i++) {
5393 if (!fsconvert_strdup((*getitem)(argv, i),
5394 &argvlist[i]))
5395 {
5396 lastarg = i;
5397 goto fail_1;
5398 }
5399 }
5400 lastarg = argc;
5401 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005402
Victor Stinner8c62be82010-05-06 00:08:46 +00005403 envlist = parse_envlist(env, &envc);
5404 if (envlist == NULL)
5405 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005406
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005408#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005409 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005410#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005411 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005412#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005414
Victor Stinner8c62be82010-05-06 00:08:46 +00005415 if (spawnval == -1)
5416 (void) posix_error();
5417 else
5418 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005419
Victor Stinner8c62be82010-05-06 00:08:46 +00005420 while (--envc >= 0)
5421 PyMem_DEL(envlist[envc]);
5422 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005423 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005424 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005425 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005426 Py_DECREF(opath);
5427 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005428}
5429#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005430#endif /* HAVE_SPAWNV */
5431
5432
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005433#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005434PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005435"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005436Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5437\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005438Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005439
5440static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005441posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005442{
Victor Stinner8c62be82010-05-06 00:08:46 +00005443 pid_t pid;
5444 int result = 0;
5445 _PyImport_AcquireLock();
5446 pid = fork1();
5447 if (pid == 0) {
5448 /* child: this clobbers and resets the import lock. */
5449 PyOS_AfterFork();
5450 } else {
5451 /* parent: release the import lock. */
5452 result = _PyImport_ReleaseLock();
5453 }
5454 if (pid == -1)
5455 return posix_error();
5456 if (result < 0) {
5457 /* Don't clobber the OSError if the fork failed. */
5458 PyErr_SetString(PyExc_RuntimeError,
5459 "not holding the import lock");
5460 return NULL;
5461 }
5462 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005463}
5464#endif
5465
5466
Guido van Rossumad0ee831995-03-01 10:34:45 +00005467#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005468PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005469"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005470Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005471Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005472
Barry Warsaw53699e91996-12-10 23:23:01 +00005473static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005474posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005475{
Victor Stinner8c62be82010-05-06 00:08:46 +00005476 pid_t pid;
5477 int result = 0;
5478 _PyImport_AcquireLock();
5479 pid = fork();
5480 if (pid == 0) {
5481 /* child: this clobbers and resets the import lock. */
5482 PyOS_AfterFork();
5483 } else {
5484 /* parent: release the import lock. */
5485 result = _PyImport_ReleaseLock();
5486 }
5487 if (pid == -1)
5488 return posix_error();
5489 if (result < 0) {
5490 /* Don't clobber the OSError if the fork failed. */
5491 PyErr_SetString(PyExc_RuntimeError,
5492 "not holding the import lock");
5493 return NULL;
5494 }
5495 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005496}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005497#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005498
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005499#ifdef HAVE_SCHED_H
5500
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005501#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5502
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005503PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5504"sched_get_priority_max(policy)\n\n\
5505Get the maximum scheduling priority for *policy*.");
5506
5507static PyObject *
5508posix_sched_get_priority_max(PyObject *self, PyObject *args)
5509{
5510 int policy, max;
5511
5512 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5513 return NULL;
5514 max = sched_get_priority_max(policy);
5515 if (max < 0)
5516 return posix_error();
5517 return PyLong_FromLong(max);
5518}
5519
5520PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5521"sched_get_priority_min(policy)\n\n\
5522Get the minimum scheduling priority for *policy*.");
5523
5524static PyObject *
5525posix_sched_get_priority_min(PyObject *self, PyObject *args)
5526{
5527 int policy, min;
5528
5529 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5530 return NULL;
5531 min = sched_get_priority_min(policy);
5532 if (min < 0)
5533 return posix_error();
5534 return PyLong_FromLong(min);
5535}
5536
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005537#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5538
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005539#ifdef HAVE_SCHED_SETSCHEDULER
5540
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005541PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5542"sched_getscheduler(pid)\n\n\
5543Get the scheduling policy for the process with a PID of *pid*.\n\
5544Passing a PID of 0 returns the scheduling policy for the calling process.");
5545
5546static PyObject *
5547posix_sched_getscheduler(PyObject *self, PyObject *args)
5548{
5549 pid_t pid;
5550 int policy;
5551
5552 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5553 return NULL;
5554 policy = sched_getscheduler(pid);
5555 if (policy < 0)
5556 return posix_error();
5557 return PyLong_FromLong(policy);
5558}
5559
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005560#endif
5561
5562#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5563
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005564static PyObject *
5565sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5566{
5567 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005568 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005569
5570 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5571 return NULL;
5572 res = PyStructSequence_New(type);
5573 if (!res)
5574 return NULL;
5575 Py_INCREF(priority);
5576 PyStructSequence_SET_ITEM(res, 0, priority);
5577 return res;
5578}
5579
5580PyDoc_STRVAR(sched_param__doc__,
5581"sched_param(sched_priority): A scheduling parameter.\n\n\
5582Current has only one field: sched_priority");
5583
5584static PyStructSequence_Field sched_param_fields[] = {
5585 {"sched_priority", "the scheduling priority"},
5586 {0}
5587};
5588
5589static PyStructSequence_Desc sched_param_desc = {
5590 "sched_param", /* name */
5591 sched_param__doc__, /* doc */
5592 sched_param_fields,
5593 1
5594};
5595
5596static int
5597convert_sched_param(PyObject *param, struct sched_param *res)
5598{
5599 long priority;
5600
5601 if (Py_TYPE(param) != &SchedParamType) {
5602 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5603 return 0;
5604 }
5605 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5606 if (priority == -1 && PyErr_Occurred())
5607 return 0;
5608 if (priority > INT_MAX || priority < INT_MIN) {
5609 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5610 return 0;
5611 }
5612 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5613 return 1;
5614}
5615
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005616#endif
5617
5618#ifdef HAVE_SCHED_SETSCHEDULER
5619
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005620PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5621"sched_setscheduler(pid, policy, param)\n\n\
5622Set the scheduling policy, *policy*, for *pid*.\n\
5623If *pid* is 0, the calling process is changed.\n\
5624*param* is an instance of sched_param.");
5625
5626static PyObject *
5627posix_sched_setscheduler(PyObject *self, PyObject *args)
5628{
5629 pid_t pid;
5630 int policy;
5631 struct sched_param param;
5632
5633 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5634 &pid, &policy, &convert_sched_param, &param))
5635 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005636
5637 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005638 ** sched_setscheduler() returns 0 in Linux, but the previous
5639 ** scheduling policy under Solaris/Illumos, and others.
5640 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005641 */
5642 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005643 return posix_error();
5644 Py_RETURN_NONE;
5645}
5646
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005647#endif
5648
5649#ifdef HAVE_SCHED_SETPARAM
5650
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005651PyDoc_STRVAR(posix_sched_getparam__doc__,
5652"sched_getparam(pid) -> sched_param\n\n\
5653Returns scheduling parameters for the process with *pid* as an instance of the\n\
5654sched_param class. A PID of 0 means the calling process.");
5655
5656static PyObject *
5657posix_sched_getparam(PyObject *self, PyObject *args)
5658{
5659 pid_t pid;
5660 struct sched_param param;
5661 PyObject *res, *priority;
5662
5663 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5664 return NULL;
5665 if (sched_getparam(pid, &param))
5666 return posix_error();
5667 res = PyStructSequence_New(&SchedParamType);
5668 if (!res)
5669 return NULL;
5670 priority = PyLong_FromLong(param.sched_priority);
5671 if (!priority) {
5672 Py_DECREF(res);
5673 return NULL;
5674 }
5675 PyStructSequence_SET_ITEM(res, 0, priority);
5676 return res;
5677}
5678
5679PyDoc_STRVAR(posix_sched_setparam__doc__,
5680"sched_setparam(pid, param)\n\n\
5681Set scheduling parameters for a process with PID *pid*.\n\
5682A PID of 0 means the calling process.");
5683
5684static PyObject *
5685posix_sched_setparam(PyObject *self, PyObject *args)
5686{
5687 pid_t pid;
5688 struct sched_param param;
5689
5690 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5691 &pid, &convert_sched_param, &param))
5692 return NULL;
5693 if (sched_setparam(pid, &param))
5694 return posix_error();
5695 Py_RETURN_NONE;
5696}
5697
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005698#endif
5699
5700#ifdef HAVE_SCHED_RR_GET_INTERVAL
5701
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005702PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5703"sched_rr_get_interval(pid) -> float\n\n\
5704Return the round-robin quantum for the process with PID *pid* in seconds.");
5705
5706static PyObject *
5707posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5708{
5709 pid_t pid;
5710 struct timespec interval;
5711
5712 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5713 return NULL;
5714 if (sched_rr_get_interval(pid, &interval))
5715 return posix_error();
5716 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5717}
5718
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005719#endif
5720
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005721PyDoc_STRVAR(posix_sched_yield__doc__,
5722"sched_yield()\n\n\
5723Voluntarily relinquish the CPU.");
5724
5725static PyObject *
5726posix_sched_yield(PyObject *self, PyObject *noargs)
5727{
5728 if (sched_yield())
5729 return posix_error();
5730 Py_RETURN_NONE;
5731}
5732
Benjamin Peterson2740af82011-08-02 17:41:34 -05005733#ifdef HAVE_SCHED_SETAFFINITY
5734
Antoine Pitrou84869872012-08-04 16:16:35 +02005735/* The minimum number of CPUs allocated in a cpu_set_t */
5736static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005737
5738PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5739"sched_setaffinity(pid, cpu_set)\n\n\
5740Set the affinity of the process with PID *pid* to *cpu_set*.");
5741
5742static PyObject *
5743posix_sched_setaffinity(PyObject *self, PyObject *args)
5744{
5745 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005746 int ncpus;
5747 size_t setsize;
5748 cpu_set_t *mask = NULL;
5749 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005750
Antoine Pitrou84869872012-08-04 16:16:35 +02005751 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5752 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005753 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005754
5755 iterator = PyObject_GetIter(iterable);
5756 if (iterator == NULL)
5757 return NULL;
5758
5759 ncpus = NCPUS_START;
5760 setsize = CPU_ALLOC_SIZE(ncpus);
5761 mask = CPU_ALLOC(ncpus);
5762 if (mask == NULL) {
5763 PyErr_NoMemory();
5764 goto error;
5765 }
5766 CPU_ZERO_S(setsize, mask);
5767
5768 while ((item = PyIter_Next(iterator))) {
5769 long cpu;
5770 if (!PyLong_Check(item)) {
5771 PyErr_Format(PyExc_TypeError,
5772 "expected an iterator of ints, "
5773 "but iterator yielded %R",
5774 Py_TYPE(item));
5775 Py_DECREF(item);
5776 goto error;
5777 }
5778 cpu = PyLong_AsLong(item);
5779 Py_DECREF(item);
5780 if (cpu < 0) {
5781 if (!PyErr_Occurred())
5782 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5783 goto error;
5784 }
5785 if (cpu > INT_MAX - 1) {
5786 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5787 goto error;
5788 }
5789 if (cpu >= ncpus) {
5790 /* Grow CPU mask to fit the CPU number */
5791 int newncpus = ncpus;
5792 cpu_set_t *newmask;
5793 size_t newsetsize;
5794 while (newncpus <= cpu) {
5795 if (newncpus > INT_MAX / 2)
5796 newncpus = cpu + 1;
5797 else
5798 newncpus = newncpus * 2;
5799 }
5800 newmask = CPU_ALLOC(newncpus);
5801 if (newmask == NULL) {
5802 PyErr_NoMemory();
5803 goto error;
5804 }
5805 newsetsize = CPU_ALLOC_SIZE(newncpus);
5806 CPU_ZERO_S(newsetsize, newmask);
5807 memcpy(newmask, mask, setsize);
5808 CPU_FREE(mask);
5809 setsize = newsetsize;
5810 mask = newmask;
5811 ncpus = newncpus;
5812 }
5813 CPU_SET_S(cpu, setsize, mask);
5814 }
5815 Py_CLEAR(iterator);
5816
5817 if (sched_setaffinity(pid, setsize, mask)) {
5818 posix_error();
5819 goto error;
5820 }
5821 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005822 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005823
5824error:
5825 if (mask)
5826 CPU_FREE(mask);
5827 Py_XDECREF(iterator);
5828 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005829}
5830
5831PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5832"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5833Return the affinity of the process with PID *pid*.\n\
5834The returned cpu_set will be of size *ncpus*.");
5835
5836static PyObject *
5837posix_sched_getaffinity(PyObject *self, PyObject *args)
5838{
5839 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005840 int cpu, ncpus, count;
5841 size_t setsize;
5842 cpu_set_t *mask = NULL;
5843 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005844
Antoine Pitrou84869872012-08-04 16:16:35 +02005845 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5846 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005847 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005848
5849 ncpus = NCPUS_START;
5850 while (1) {
5851 setsize = CPU_ALLOC_SIZE(ncpus);
5852 mask = CPU_ALLOC(ncpus);
5853 if (mask == NULL)
5854 return PyErr_NoMemory();
5855 if (sched_getaffinity(pid, setsize, mask) == 0)
5856 break;
5857 CPU_FREE(mask);
5858 if (errno != EINVAL)
5859 return posix_error();
5860 if (ncpus > INT_MAX / 2) {
5861 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5862 "a large enough CPU set");
5863 return NULL;
5864 }
5865 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005866 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005867
5868 res = PySet_New(NULL);
5869 if (res == NULL)
5870 goto error;
5871 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5872 if (CPU_ISSET_S(cpu, setsize, mask)) {
5873 PyObject *cpu_num = PyLong_FromLong(cpu);
5874 --count;
5875 if (cpu_num == NULL)
5876 goto error;
5877 if (PySet_Add(res, cpu_num)) {
5878 Py_DECREF(cpu_num);
5879 goto error;
5880 }
5881 Py_DECREF(cpu_num);
5882 }
5883 }
5884 CPU_FREE(mask);
5885 return res;
5886
5887error:
5888 if (mask)
5889 CPU_FREE(mask);
5890 Py_XDECREF(res);
5891 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005892}
5893
Benjamin Peterson2740af82011-08-02 17:41:34 -05005894#endif /* HAVE_SCHED_SETAFFINITY */
5895
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005896#endif /* HAVE_SCHED_H */
5897
Neal Norwitzb59798b2003-03-21 01:43:31 +00005898/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005899/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5900#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005901#define DEV_PTY_FILE "/dev/ptc"
5902#define HAVE_DEV_PTMX
5903#else
5904#define DEV_PTY_FILE "/dev/ptmx"
5905#endif
5906
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005907#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005908#ifdef HAVE_PTY_H
5909#include <pty.h>
5910#else
5911#ifdef HAVE_LIBUTIL_H
5912#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005913#else
5914#ifdef HAVE_UTIL_H
5915#include <util.h>
5916#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005917#endif /* HAVE_LIBUTIL_H */
5918#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005919#ifdef HAVE_STROPTS_H
5920#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005921#endif
5922#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005923
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005924#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005925PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005926"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005927Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005928
5929static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005930posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005931{
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005933#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005934 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005935#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005936#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005937 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005938#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005939 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005940#endif
5941#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005942
Thomas Wouters70c21a12000-07-14 14:28:33 +00005943#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5945 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005946#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005947 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5948 if (slave_name == NULL)
5949 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005950
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 slave_fd = open(slave_name, O_RDWR);
5952 if (slave_fd < 0)
5953 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005954#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005955 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5956 if (master_fd < 0)
5957 return posix_error();
5958 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5959 /* change permission of slave */
5960 if (grantpt(master_fd) < 0) {
5961 PyOS_setsig(SIGCHLD, sig_saved);
5962 return posix_error();
5963 }
5964 /* unlock slave */
5965 if (unlockpt(master_fd) < 0) {
5966 PyOS_setsig(SIGCHLD, sig_saved);
5967 return posix_error();
5968 }
5969 PyOS_setsig(SIGCHLD, sig_saved);
5970 slave_name = ptsname(master_fd); /* get name of slave */
5971 if (slave_name == NULL)
5972 return posix_error();
5973 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5974 if (slave_fd < 0)
5975 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005976#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5978 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005979#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005980 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005981#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005982#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005983#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005984
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005986
Fred Drake8cef4cf2000-06-28 16:40:38 +00005987}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005988#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005989
5990#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005992"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005993Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5994Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005995To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005996
5997static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005998posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005999{
Victor Stinner8c62be82010-05-06 00:08:46 +00006000 int master_fd = -1, result = 0;
6001 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006002
Victor Stinner8c62be82010-05-06 00:08:46 +00006003 _PyImport_AcquireLock();
6004 pid = forkpty(&master_fd, NULL, NULL, NULL);
6005 if (pid == 0) {
6006 /* child: this clobbers and resets the import lock. */
6007 PyOS_AfterFork();
6008 } else {
6009 /* parent: release the import lock. */
6010 result = _PyImport_ReleaseLock();
6011 }
6012 if (pid == -1)
6013 return posix_error();
6014 if (result < 0) {
6015 /* Don't clobber the OSError if the fork failed. */
6016 PyErr_SetString(PyExc_RuntimeError,
6017 "not holding the import lock");
6018 return NULL;
6019 }
6020 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006021}
6022#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006023
Ross Lagerwall7807c352011-03-17 20:20:30 +02006024
Guido van Rossumad0ee831995-03-01 10:34:45 +00006025#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006026PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006027"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006028Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006029
Barry Warsaw53699e91996-12-10 23:23:01 +00006030static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006031posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006032{
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006034}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006035#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006036
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006037
Guido van Rossumad0ee831995-03-01 10:34:45 +00006038#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006039PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006040"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006041Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006042
Barry Warsaw53699e91996-12-10 23:23:01 +00006043static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006044posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006045{
Victor Stinner8c62be82010-05-06 00:08:46 +00006046 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006047}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006048#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006049
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006050
Guido van Rossumad0ee831995-03-01 10:34:45 +00006051#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006052PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006053"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006054Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006055
Barry Warsaw53699e91996-12-10 23:23:01 +00006056static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006057posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006058{
Victor Stinner8c62be82010-05-06 00:08:46 +00006059 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006060}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006061#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006062
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006063
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006064PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006065"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006066Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006067
Barry Warsaw53699e91996-12-10 23:23:01 +00006068static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006069posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006070{
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006072}
6073
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006074#ifdef HAVE_GETGROUPLIST
6075PyDoc_STRVAR(posix_getgrouplist__doc__,
6076"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6077Returns a list of groups to which a user belongs.\n\n\
6078 user: username to lookup\n\
6079 group: base group id of the user");
6080
6081static PyObject *
6082posix_getgrouplist(PyObject *self, PyObject *args)
6083{
6084#ifdef NGROUPS_MAX
6085#define MAX_GROUPS NGROUPS_MAX
6086#else
6087 /* defined to be 16 on Solaris7, so this should be a small number */
6088#define MAX_GROUPS 64
6089#endif
6090
6091 const char *user;
6092 int i, ngroups;
6093 PyObject *list;
6094#ifdef __APPLE__
6095 int *groups, basegid;
6096#else
6097 gid_t *groups, basegid;
6098#endif
6099 ngroups = MAX_GROUPS;
6100
6101 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
6102 return NULL;
6103
6104#ifdef __APPLE__
6105 groups = PyMem_Malloc(ngroups * sizeof(int));
6106#else
6107 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6108#endif
6109 if (groups == NULL)
6110 return PyErr_NoMemory();
6111
6112 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6113 PyMem_Del(groups);
6114 return posix_error();
6115 }
6116
6117 list = PyList_New(ngroups);
6118 if (list == NULL) {
6119 PyMem_Del(groups);
6120 return NULL;
6121 }
6122
6123 for (i = 0; i < ngroups; i++) {
6124 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
6125 if (o == NULL) {
6126 Py_DECREF(list);
6127 PyMem_Del(groups);
6128 return NULL;
6129 }
6130 PyList_SET_ITEM(list, i, o);
6131 }
6132
6133 PyMem_Del(groups);
6134
6135 return list;
6136}
6137#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006138
Fred Drakec9680921999-12-13 16:37:25 +00006139#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006140PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006141"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006142Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006143
6144static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006145posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006146{
6147 PyObject *result = NULL;
6148
Fred Drakec9680921999-12-13 16:37:25 +00006149#ifdef NGROUPS_MAX
6150#define MAX_GROUPS NGROUPS_MAX
6151#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006152 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006153#define MAX_GROUPS 64
6154#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006155 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006156
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006157 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006158 * This is a helper variable to store the intermediate result when
6159 * that happens.
6160 *
6161 * To keep the code readable the OSX behaviour is unconditional,
6162 * according to the POSIX spec this should be safe on all unix-y
6163 * systems.
6164 */
6165 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006166 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006167
Victor Stinner8c62be82010-05-06 00:08:46 +00006168 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006169 if (n < 0) {
6170 if (errno == EINVAL) {
6171 n = getgroups(0, NULL);
6172 if (n == -1) {
6173 return posix_error();
6174 }
6175 if (n == 0) {
6176 /* Avoid malloc(0) */
6177 alt_grouplist = grouplist;
6178 } else {
6179 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6180 if (alt_grouplist == NULL) {
6181 errno = EINVAL;
6182 return posix_error();
6183 }
6184 n = getgroups(n, alt_grouplist);
6185 if (n == -1) {
6186 PyMem_Free(alt_grouplist);
6187 return posix_error();
6188 }
6189 }
6190 } else {
6191 return posix_error();
6192 }
6193 }
6194 result = PyList_New(n);
6195 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 int i;
6197 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006198 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006200 Py_DECREF(result);
6201 result = NULL;
6202 break;
Fred Drakec9680921999-12-13 16:37:25 +00006203 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006205 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006206 }
6207
6208 if (alt_grouplist != grouplist) {
6209 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006210 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006211
Fred Drakec9680921999-12-13 16:37:25 +00006212 return result;
6213}
6214#endif
6215
Antoine Pitroub7572f02009-12-02 20:46:48 +00006216#ifdef HAVE_INITGROUPS
6217PyDoc_STRVAR(posix_initgroups__doc__,
6218"initgroups(username, gid) -> None\n\n\
6219Call the system initgroups() to initialize the group access list with all of\n\
6220the groups of which the specified username is a member, plus the specified\n\
6221group id.");
6222
6223static PyObject *
6224posix_initgroups(PyObject *self, PyObject *args)
6225{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006226 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006227 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006228 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006229 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006230
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006231 if (!PyArg_ParseTuple(args, "O&l:initgroups",
6232 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006233 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006234 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006235
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006236 res = initgroups(username, (gid_t) gid);
6237 Py_DECREF(oname);
6238 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006239 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006240
Victor Stinner8c62be82010-05-06 00:08:46 +00006241 Py_INCREF(Py_None);
6242 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006243}
6244#endif
6245
Martin v. Löwis606edc12002-06-13 21:09:11 +00006246#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006247PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006248"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006249Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006250
6251static PyObject *
6252posix_getpgid(PyObject *self, PyObject *args)
6253{
Victor Stinner8c62be82010-05-06 00:08:46 +00006254 pid_t pid, pgid;
6255 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6256 return NULL;
6257 pgid = getpgid(pid);
6258 if (pgid < 0)
6259 return posix_error();
6260 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006261}
6262#endif /* HAVE_GETPGID */
6263
6264
Guido van Rossumb6775db1994-08-01 11:34:53 +00006265#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006266PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006267"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006268Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006269
Barry Warsaw53699e91996-12-10 23:23:01 +00006270static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006271posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006272{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006273#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006274 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006275#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006276 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006277#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006278}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006279#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006281
Guido van Rossumb6775db1994-08-01 11:34:53 +00006282#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006283PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006284"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006285Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006286
Barry Warsaw53699e91996-12-10 23:23:01 +00006287static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006288posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006289{
Guido van Rossum64933891994-10-20 21:56:42 +00006290#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006292#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006294#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006295 return posix_error();
6296 Py_INCREF(Py_None);
6297 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006298}
6299
Guido van Rossumb6775db1994-08-01 11:34:53 +00006300#endif /* HAVE_SETPGRP */
6301
Guido van Rossumad0ee831995-03-01 10:34:45 +00006302#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006303
6304#ifdef MS_WINDOWS
6305#include <tlhelp32.h>
6306
6307static PyObject*
6308win32_getppid()
6309{
6310 HANDLE snapshot;
6311 pid_t mypid;
6312 PyObject* result = NULL;
6313 BOOL have_record;
6314 PROCESSENTRY32 pe;
6315
6316 mypid = getpid(); /* This function never fails */
6317
6318 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6319 if (snapshot == INVALID_HANDLE_VALUE)
6320 return PyErr_SetFromWindowsErr(GetLastError());
6321
6322 pe.dwSize = sizeof(pe);
6323 have_record = Process32First(snapshot, &pe);
6324 while (have_record) {
6325 if (mypid == (pid_t)pe.th32ProcessID) {
6326 /* We could cache the ulong value in a static variable. */
6327 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6328 break;
6329 }
6330
6331 have_record = Process32Next(snapshot, &pe);
6332 }
6333
6334 /* If our loop exits and our pid was not found (result will be NULL)
6335 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6336 * error anyway, so let's raise it. */
6337 if (!result)
6338 result = PyErr_SetFromWindowsErr(GetLastError());
6339
6340 CloseHandle(snapshot);
6341
6342 return result;
6343}
6344#endif /*MS_WINDOWS*/
6345
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006346PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006347"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006348Return the parent's process id. If the parent process has already exited,\n\
6349Windows machines will still return its id; others systems will return the id\n\
6350of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006351
Barry Warsaw53699e91996-12-10 23:23:01 +00006352static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006353posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006354{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006355#ifdef MS_WINDOWS
6356 return win32_getppid();
6357#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006359#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006360}
6361#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006362
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006363
Fred Drake12c6e2d1999-12-14 21:25:03 +00006364#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006365PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006366"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006367Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006368
6369static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006370posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006371{
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006373#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006374 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006375 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006376
6377 if (GetUserNameW(user_name, &num_chars)) {
6378 /* num_chars is the number of unicode chars plus null terminator */
6379 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006380 }
6381 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006382 result = PyErr_SetFromWindowsErr(GetLastError());
6383#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 char *name;
6385 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006386
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 errno = 0;
6388 name = getlogin();
6389 if (name == NULL) {
6390 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006391 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006392 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006393 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006394 }
6395 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006396 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006398#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006399 return result;
6400}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006401#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006402
Guido van Rossumad0ee831995-03-01 10:34:45 +00006403#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006404PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006405"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006406Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006407
Barry Warsaw53699e91996-12-10 23:23:01 +00006408static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006409posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006410{
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006412}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006413#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006414
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006415
Guido van Rossumad0ee831995-03-01 10:34:45 +00006416#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006417PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006418"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006419Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006420
Barry Warsaw53699e91996-12-10 23:23:01 +00006421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006422posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006423{
Victor Stinner8c62be82010-05-06 00:08:46 +00006424 pid_t pid;
6425 int sig;
6426 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6427 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006428#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006429 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6430 APIRET rc;
6431 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006432 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006433
6434 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6435 APIRET rc;
6436 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006437 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006438
6439 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006440 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006441#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006442 if (kill(pid, sig) == -1)
6443 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006444#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 Py_INCREF(Py_None);
6446 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006447}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006448#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006449
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006450#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006451PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006452"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006453Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006454
6455static PyObject *
6456posix_killpg(PyObject *self, PyObject *args)
6457{
Victor Stinner8c62be82010-05-06 00:08:46 +00006458 int sig;
6459 pid_t pgid;
6460 /* XXX some man pages make the `pgid` parameter an int, others
6461 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6462 take the same type. Moreover, pid_t is always at least as wide as
6463 int (else compilation of this module fails), which is safe. */
6464 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6465 return NULL;
6466 if (killpg(pgid, sig) == -1)
6467 return posix_error();
6468 Py_INCREF(Py_None);
6469 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006470}
6471#endif
6472
Brian Curtineb24d742010-04-12 17:16:38 +00006473#ifdef MS_WINDOWS
6474PyDoc_STRVAR(win32_kill__doc__,
6475"kill(pid, sig)\n\n\
6476Kill a process with a signal.");
6477
6478static PyObject *
6479win32_kill(PyObject *self, PyObject *args)
6480{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006481 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006482 DWORD pid, sig, err;
6483 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006484
Victor Stinner8c62be82010-05-06 00:08:46 +00006485 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6486 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006487
Victor Stinner8c62be82010-05-06 00:08:46 +00006488 /* Console processes which share a common console can be sent CTRL+C or
6489 CTRL+BREAK events, provided they handle said events. */
6490 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6491 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6492 err = GetLastError();
6493 PyErr_SetFromWindowsErr(err);
6494 }
6495 else
6496 Py_RETURN_NONE;
6497 }
Brian Curtineb24d742010-04-12 17:16:38 +00006498
Victor Stinner8c62be82010-05-06 00:08:46 +00006499 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6500 attempt to open and terminate the process. */
6501 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6502 if (handle == NULL) {
6503 err = GetLastError();
6504 return PyErr_SetFromWindowsErr(err);
6505 }
Brian Curtineb24d742010-04-12 17:16:38 +00006506
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 if (TerminateProcess(handle, sig) == 0) {
6508 err = GetLastError();
6509 result = PyErr_SetFromWindowsErr(err);
6510 } else {
6511 Py_INCREF(Py_None);
6512 result = Py_None;
6513 }
Brian Curtineb24d742010-04-12 17:16:38 +00006514
Victor Stinner8c62be82010-05-06 00:08:46 +00006515 CloseHandle(handle);
6516 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006517}
6518#endif /* MS_WINDOWS */
6519
Guido van Rossumc0125471996-06-28 18:55:32 +00006520#ifdef HAVE_PLOCK
6521
6522#ifdef HAVE_SYS_LOCK_H
6523#include <sys/lock.h>
6524#endif
6525
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006526PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006527"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006528Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006529
Barry Warsaw53699e91996-12-10 23:23:01 +00006530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006531posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006532{
Victor Stinner8c62be82010-05-06 00:08:46 +00006533 int op;
6534 if (!PyArg_ParseTuple(args, "i:plock", &op))
6535 return NULL;
6536 if (plock(op) == -1)
6537 return posix_error();
6538 Py_INCREF(Py_None);
6539 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006540}
6541#endif
6542
Guido van Rossumb6775db1994-08-01 11:34:53 +00006543#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006544PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006545"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006546Set the current process's user id.");
6547
Barry Warsaw53699e91996-12-10 23:23:01 +00006548static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006549posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006550{
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 long uid_arg;
6552 uid_t uid;
6553 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6554 return NULL;
6555 uid = uid_arg;
6556 if (uid != uid_arg) {
6557 PyErr_SetString(PyExc_OverflowError, "user id too big");
6558 return NULL;
6559 }
6560 if (setuid(uid) < 0)
6561 return posix_error();
6562 Py_INCREF(Py_None);
6563 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006564}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006565#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006566
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006567
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006568#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006569PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006570"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006571Set the current process's effective user id.");
6572
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006573static PyObject *
6574posix_seteuid (PyObject *self, PyObject *args)
6575{
Victor Stinner8c62be82010-05-06 00:08:46 +00006576 long euid_arg;
6577 uid_t euid;
6578 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6579 return NULL;
6580 euid = euid_arg;
6581 if (euid != euid_arg) {
6582 PyErr_SetString(PyExc_OverflowError, "user id too big");
6583 return NULL;
6584 }
6585 if (seteuid(euid) < 0) {
6586 return posix_error();
6587 } else {
6588 Py_INCREF(Py_None);
6589 return Py_None;
6590 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006591}
6592#endif /* HAVE_SETEUID */
6593
6594#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006595PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006596"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006597Set the current process's effective group id.");
6598
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006599static PyObject *
6600posix_setegid (PyObject *self, PyObject *args)
6601{
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 long egid_arg;
6603 gid_t egid;
6604 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6605 return NULL;
6606 egid = egid_arg;
6607 if (egid != egid_arg) {
6608 PyErr_SetString(PyExc_OverflowError, "group id too big");
6609 return NULL;
6610 }
6611 if (setegid(egid) < 0) {
6612 return posix_error();
6613 } else {
6614 Py_INCREF(Py_None);
6615 return Py_None;
6616 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006617}
6618#endif /* HAVE_SETEGID */
6619
6620#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006621PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006622"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623Set the current process's real and effective user ids.");
6624
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006625static PyObject *
6626posix_setreuid (PyObject *self, PyObject *args)
6627{
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 long ruid_arg, euid_arg;
6629 uid_t ruid, euid;
6630 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6631 return NULL;
6632 if (ruid_arg == -1)
6633 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6634 else
6635 ruid = ruid_arg; /* otherwise, assign from our long */
6636 if (euid_arg == -1)
6637 euid = (uid_t)-1;
6638 else
6639 euid = euid_arg;
6640 if ((euid_arg != -1 && euid != euid_arg) ||
6641 (ruid_arg != -1 && ruid != ruid_arg)) {
6642 PyErr_SetString(PyExc_OverflowError, "user id too big");
6643 return NULL;
6644 }
6645 if (setreuid(ruid, euid) < 0) {
6646 return posix_error();
6647 } else {
6648 Py_INCREF(Py_None);
6649 return Py_None;
6650 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006651}
6652#endif /* HAVE_SETREUID */
6653
6654#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006655PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006656"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006657Set the current process's real and effective group ids.");
6658
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006659static PyObject *
6660posix_setregid (PyObject *self, PyObject *args)
6661{
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 long rgid_arg, egid_arg;
6663 gid_t rgid, egid;
6664 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6665 return NULL;
6666 if (rgid_arg == -1)
6667 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6668 else
6669 rgid = rgid_arg; /* otherwise, assign from our long */
6670 if (egid_arg == -1)
6671 egid = (gid_t)-1;
6672 else
6673 egid = egid_arg;
6674 if ((egid_arg != -1 && egid != egid_arg) ||
6675 (rgid_arg != -1 && rgid != rgid_arg)) {
6676 PyErr_SetString(PyExc_OverflowError, "group id too big");
6677 return NULL;
6678 }
6679 if (setregid(rgid, egid) < 0) {
6680 return posix_error();
6681 } else {
6682 Py_INCREF(Py_None);
6683 return Py_None;
6684 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006685}
6686#endif /* HAVE_SETREGID */
6687
Guido van Rossumb6775db1994-08-01 11:34:53 +00006688#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006689PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006690"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006691Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006692
Barry Warsaw53699e91996-12-10 23:23:01 +00006693static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006694posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006695{
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 long gid_arg;
6697 gid_t gid;
6698 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6699 return NULL;
6700 gid = gid_arg;
6701 if (gid != gid_arg) {
6702 PyErr_SetString(PyExc_OverflowError, "group id too big");
6703 return NULL;
6704 }
6705 if (setgid(gid) < 0)
6706 return posix_error();
6707 Py_INCREF(Py_None);
6708 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006709}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006710#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006711
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006712#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006713PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006714"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006715Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006716
6717static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006718posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006719{
Victor Stinner8c62be82010-05-06 00:08:46 +00006720 int i, len;
6721 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006722
Victor Stinner8c62be82010-05-06 00:08:46 +00006723 if (!PySequence_Check(groups)) {
6724 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6725 return NULL;
6726 }
6727 len = PySequence_Size(groups);
6728 if (len > MAX_GROUPS) {
6729 PyErr_SetString(PyExc_ValueError, "too many groups");
6730 return NULL;
6731 }
6732 for(i = 0; i < len; i++) {
6733 PyObject *elem;
6734 elem = PySequence_GetItem(groups, i);
6735 if (!elem)
6736 return NULL;
6737 if (!PyLong_Check(elem)) {
6738 PyErr_SetString(PyExc_TypeError,
6739 "groups must be integers");
6740 Py_DECREF(elem);
6741 return NULL;
6742 } else {
6743 unsigned long x = PyLong_AsUnsignedLong(elem);
6744 if (PyErr_Occurred()) {
6745 PyErr_SetString(PyExc_TypeError,
6746 "group id too big");
6747 Py_DECREF(elem);
6748 return NULL;
6749 }
6750 grouplist[i] = x;
6751 /* read back the value to see if it fitted in gid_t */
6752 if (grouplist[i] != x) {
6753 PyErr_SetString(PyExc_TypeError,
6754 "group id too big");
6755 Py_DECREF(elem);
6756 return NULL;
6757 }
6758 }
6759 Py_DECREF(elem);
6760 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006761
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 if (setgroups(len, grouplist) < 0)
6763 return posix_error();
6764 Py_INCREF(Py_None);
6765 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006766}
6767#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006768
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006769#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6770static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006771wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006772{
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 PyObject *result;
6774 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006775 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006776
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 if (pid == -1)
6778 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006779
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 if (struct_rusage == NULL) {
6781 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6782 if (m == NULL)
6783 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006784 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 Py_DECREF(m);
6786 if (struct_rusage == NULL)
6787 return NULL;
6788 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006789
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6791 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6792 if (!result)
6793 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006794
6795#ifndef doubletime
6796#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6797#endif
6798
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006800 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006802 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006803#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6805 SET_INT(result, 2, ru->ru_maxrss);
6806 SET_INT(result, 3, ru->ru_ixrss);
6807 SET_INT(result, 4, ru->ru_idrss);
6808 SET_INT(result, 5, ru->ru_isrss);
6809 SET_INT(result, 6, ru->ru_minflt);
6810 SET_INT(result, 7, ru->ru_majflt);
6811 SET_INT(result, 8, ru->ru_nswap);
6812 SET_INT(result, 9, ru->ru_inblock);
6813 SET_INT(result, 10, ru->ru_oublock);
6814 SET_INT(result, 11, ru->ru_msgsnd);
6815 SET_INT(result, 12, ru->ru_msgrcv);
6816 SET_INT(result, 13, ru->ru_nsignals);
6817 SET_INT(result, 14, ru->ru_nvcsw);
6818 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006819#undef SET_INT
6820
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 if (PyErr_Occurred()) {
6822 Py_DECREF(result);
6823 return NULL;
6824 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006827}
6828#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6829
6830#ifdef HAVE_WAIT3
6831PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006832"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006833Wait for completion of a child process.");
6834
6835static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006836posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006837{
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 pid_t pid;
6839 int options;
6840 struct rusage ru;
6841 WAIT_TYPE status;
6842 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006843
Victor Stinner4195b5c2012-02-08 23:03:19 +01006844 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006846
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 Py_BEGIN_ALLOW_THREADS
6848 pid = wait3(&status, options, &ru);
6849 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006850
Victor Stinner4195b5c2012-02-08 23:03:19 +01006851 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006852}
6853#endif /* HAVE_WAIT3 */
6854
6855#ifdef HAVE_WAIT4
6856PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006857"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006858Wait for completion of a given child process.");
6859
6860static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006861posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006862{
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 pid_t pid;
6864 int options;
6865 struct rusage ru;
6866 WAIT_TYPE status;
6867 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006868
Victor Stinner4195b5c2012-02-08 23:03:19 +01006869 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006871
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 Py_BEGIN_ALLOW_THREADS
6873 pid = wait4(pid, &status, options, &ru);
6874 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006875
Victor Stinner4195b5c2012-02-08 23:03:19 +01006876 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006877}
6878#endif /* HAVE_WAIT4 */
6879
Ross Lagerwall7807c352011-03-17 20:20:30 +02006880#if defined(HAVE_WAITID) && !defined(__APPLE__)
6881PyDoc_STRVAR(posix_waitid__doc__,
6882"waitid(idtype, id, options) -> waitid_result\n\n\
6883Wait for the completion of one or more child processes.\n\n\
6884idtype can be P_PID, P_PGID or P_ALL.\n\
6885id specifies the pid to wait on.\n\
6886options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6887or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6888Returns either waitid_result or None if WNOHANG is specified and there are\n\
6889no children in a waitable state.");
6890
6891static PyObject *
6892posix_waitid(PyObject *self, PyObject *args)
6893{
6894 PyObject *result;
6895 idtype_t idtype;
6896 id_t id;
6897 int options, res;
6898 siginfo_t si;
6899 si.si_pid = 0;
6900 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6901 return NULL;
6902 Py_BEGIN_ALLOW_THREADS
6903 res = waitid(idtype, id, &si, options);
6904 Py_END_ALLOW_THREADS
6905 if (res == -1)
6906 return posix_error();
6907
6908 if (si.si_pid == 0)
6909 Py_RETURN_NONE;
6910
6911 result = PyStructSequence_New(&WaitidResultType);
6912 if (!result)
6913 return NULL;
6914
6915 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6916 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6917 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6918 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6919 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6920 if (PyErr_Occurred()) {
6921 Py_DECREF(result);
6922 return NULL;
6923 }
6924
6925 return result;
6926}
6927#endif
6928
Guido van Rossumb6775db1994-08-01 11:34:53 +00006929#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006930PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006931"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006932Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006933
Barry Warsaw53699e91996-12-10 23:23:01 +00006934static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006935posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006936{
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 pid_t pid;
6938 int options;
6939 WAIT_TYPE status;
6940 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006941
Victor Stinner8c62be82010-05-06 00:08:46 +00006942 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6943 return NULL;
6944 Py_BEGIN_ALLOW_THREADS
6945 pid = waitpid(pid, &status, options);
6946 Py_END_ALLOW_THREADS
6947 if (pid == -1)
6948 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006949
Victor Stinner8c62be82010-05-06 00:08:46 +00006950 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006951}
6952
Tim Petersab034fa2002-02-01 11:27:43 +00006953#elif defined(HAVE_CWAIT)
6954
6955/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006956PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006957"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006958"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006959
6960static PyObject *
6961posix_waitpid(PyObject *self, PyObject *args)
6962{
Victor Stinner8c62be82010-05-06 00:08:46 +00006963 Py_intptr_t pid;
6964 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006965
Victor Stinner8c62be82010-05-06 00:08:46 +00006966 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6967 return NULL;
6968 Py_BEGIN_ALLOW_THREADS
6969 pid = _cwait(&status, pid, options);
6970 Py_END_ALLOW_THREADS
6971 if (pid == -1)
6972 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006973
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 /* shift the status left a byte so this is more like the POSIX waitpid */
6975 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006976}
6977#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006978
Guido van Rossumad0ee831995-03-01 10:34:45 +00006979#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006980PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006981"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006982Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006983
Barry Warsaw53699e91996-12-10 23:23:01 +00006984static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006985posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006986{
Victor Stinner8c62be82010-05-06 00:08:46 +00006987 pid_t pid;
6988 WAIT_TYPE status;
6989 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006990
Victor Stinner8c62be82010-05-06 00:08:46 +00006991 Py_BEGIN_ALLOW_THREADS
6992 pid = wait(&status);
6993 Py_END_ALLOW_THREADS
6994 if (pid == -1)
6995 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006996
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006998}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006999#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007001
Larry Hastings9cf065c2012-06-22 16:30:09 -07007002#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7003PyDoc_STRVAR(readlink__doc__,
7004"readlink(path, *, dir_fd=None) -> path\n\n\
7005Return a string representing the path to which the symbolic link points.\n\
7006\n\
7007If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7008 and path should be relative; path will then be relative to that directory.\n\
7009dir_fd may not be implemented on your platform.\n\
7010 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007011#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007012
Guido van Rossumb6775db1994-08-01 11:34:53 +00007013#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007014
Barry Warsaw53699e91996-12-10 23:23:01 +00007015static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007016posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007017{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007018 path_t path;
7019 int dir_fd = DEFAULT_DIR_FD;
7020 char buffer[MAXPATHLEN];
7021 ssize_t length;
7022 PyObject *return_value = NULL;
7023 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007024
Larry Hastings9cf065c2012-06-22 16:30:09 -07007025 memset(&path, 0, sizeof(path));
7026 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7027 path_converter, &path,
7028#ifdef HAVE_READLINKAT
7029 dir_fd_converter, &dir_fd
7030#else
7031 dir_fd_unavailable, &dir_fd
7032#endif
7033 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007035
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007037#ifdef HAVE_READLINKAT
7038 if (dir_fd != DEFAULT_DIR_FD)
7039 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007040 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007041#endif
7042 length = readlink(path.narrow, buffer, sizeof(buffer));
7043 Py_END_ALLOW_THREADS
7044
7045 if (length < 0) {
7046 return_value = path_posix_error("readlink", &path);
7047 goto exit;
7048 }
7049
7050 if (PyUnicode_Check(path.object))
7051 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7052 else
7053 return_value = PyBytes_FromStringAndSize(buffer, length);
7054exit:
7055 path_cleanup(&path);
7056 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007057}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007058
7059
Guido van Rossumb6775db1994-08-01 11:34:53 +00007060#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007062
Larry Hastings9cf065c2012-06-22 16:30:09 -07007063#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007064PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007065"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7066Create a symbolic link pointing to src named dst.\n\n\
7067target_is_directory is required on Windows if the target is to be\n\
7068 interpreted as a directory. (On Windows, symlink requires\n\
7069 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7070 target_is_directory is ignored on non-Windows platforms.\n\
7071\n\
7072If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7073 and path should be relative; path will then be relative to that directory.\n\
7074dir_fd may not be implemented on your platform.\n\
7075 If it is unavailable, using it will raise a NotImplementedError.");
7076
7077#if defined(MS_WINDOWS)
7078
7079/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7080static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7081static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7082static int
7083check_CreateSymbolicLink()
7084{
7085 HINSTANCE hKernel32;
7086 /* only recheck */
7087 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7088 return 1;
7089 hKernel32 = GetModuleHandleW(L"KERNEL32");
7090 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7091 "CreateSymbolicLinkW");
7092 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7093 "CreateSymbolicLinkA");
7094 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7095}
7096
7097#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007098
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007099static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007100posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007101{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007102 path_t src;
7103 path_t dst;
7104 int dir_fd = DEFAULT_DIR_FD;
7105 int target_is_directory = 0;
7106 static char *keywords[] = {"src", "dst", "target_is_directory",
7107 "dir_fd", NULL};
7108 PyObject *return_value;
7109#ifdef MS_WINDOWS
7110 DWORD result;
7111#else
7112 int result;
7113#endif
7114
7115 memset(&src, 0, sizeof(src));
7116 src.argument_name = "src";
7117 memset(&dst, 0, sizeof(dst));
7118 dst.argument_name = "dst";
7119
7120#ifdef MS_WINDOWS
7121 if (!check_CreateSymbolicLink()) {
7122 PyErr_SetString(PyExc_NotImplementedError,
7123 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007124 return NULL;
7125 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126 if (!win32_can_symlink) {
7127 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007128 return NULL;
7129 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130#endif
7131
7132 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7133 keywords,
7134 path_converter, &src,
7135 path_converter, &dst,
7136 &target_is_directory,
7137#ifdef HAVE_SYMLINKAT
7138 dir_fd_converter, &dir_fd
7139#else
7140 dir_fd_unavailable, &dir_fd
7141#endif
7142 ))
7143 return NULL;
7144
7145 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7146 PyErr_SetString(PyExc_ValueError,
7147 "symlink: src and dst must be the same type");
7148 return_value = NULL;
7149 goto exit;
7150 }
7151
7152#ifdef MS_WINDOWS
7153 Py_BEGIN_ALLOW_THREADS
7154 if (dst.wide)
7155 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7156 target_is_directory);
7157 else
7158 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7159 target_is_directory);
7160 Py_END_ALLOW_THREADS
7161
7162 if (!result) {
7163 return_value = win32_error_object("symlink", src.object);
7164 goto exit;
7165 }
7166
7167#else
7168
7169 Py_BEGIN_ALLOW_THREADS
7170#if HAVE_SYMLINKAT
7171 if (dir_fd != DEFAULT_DIR_FD)
7172 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7173 else
7174#endif
7175 result = symlink(src.narrow, dst.narrow);
7176 Py_END_ALLOW_THREADS
7177
7178 if (result) {
7179 return_value = path_error("symlink", &dst);
7180 goto exit;
7181 }
7182#endif
7183
7184 return_value = Py_None;
7185 Py_INCREF(Py_None);
7186 goto exit; /* silence "unused label" warning */
7187exit:
7188 path_cleanup(&src);
7189 path_cleanup(&dst);
7190 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007191}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007192
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007193#endif /* HAVE_SYMLINK */
7194
Larry Hastings9cf065c2012-06-22 16:30:09 -07007195
Brian Curtind40e6f72010-07-08 21:39:08 +00007196#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7197
Brian Curtind40e6f72010-07-08 21:39:08 +00007198static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007199win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007200{
7201 wchar_t *path;
7202 DWORD n_bytes_returned;
7203 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007204 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007205 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007206 HANDLE reparse_point_handle;
7207
7208 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7209 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7210 wchar_t *print_name;
7211
Larry Hastings9cf065c2012-06-22 16:30:09 -07007212 static char *keywords[] = {"path", "dir_fd", NULL};
7213
7214 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7215 &po,
7216 dir_fd_unavailable, &dir_fd
7217 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007218 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007219
Victor Stinnereb5657a2011-09-30 01:44:27 +02007220 path = PyUnicode_AsUnicode(po);
7221 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007222 return NULL;
7223
7224 /* First get a handle to the reparse point */
7225 Py_BEGIN_ALLOW_THREADS
7226 reparse_point_handle = CreateFileW(
7227 path,
7228 0,
7229 0,
7230 0,
7231 OPEN_EXISTING,
7232 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7233 0);
7234 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007235
Brian Curtind40e6f72010-07-08 21:39:08 +00007236 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007237 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007238
Brian Curtind40e6f72010-07-08 21:39:08 +00007239 Py_BEGIN_ALLOW_THREADS
7240 /* New call DeviceIoControl to read the reparse point */
7241 io_result = DeviceIoControl(
7242 reparse_point_handle,
7243 FSCTL_GET_REPARSE_POINT,
7244 0, 0, /* in buffer */
7245 target_buffer, sizeof(target_buffer),
7246 &n_bytes_returned,
7247 0 /* we're not using OVERLAPPED_IO */
7248 );
7249 CloseHandle(reparse_point_handle);
7250 Py_END_ALLOW_THREADS
7251
7252 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007253 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007254
7255 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7256 {
7257 PyErr_SetString(PyExc_ValueError,
7258 "not a symbolic link");
7259 return NULL;
7260 }
Brian Curtin74e45612010-07-09 15:58:59 +00007261 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7262 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7263
7264 result = PyUnicode_FromWideChar(print_name,
7265 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007266 return result;
7267}
7268
7269#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7270
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007271
Larry Hastings605a62d2012-06-24 04:33:36 -07007272static PyStructSequence_Field times_result_fields[] = {
7273 {"user", "user time"},
7274 {"system", "system time"},
7275 {"children_user", "user time of children"},
7276 {"children_system", "system time of children"},
7277 {"elapsed", "elapsed time since an arbitrary point in the past"},
7278 {NULL}
7279};
7280
7281PyDoc_STRVAR(times_result__doc__,
7282"times_result: Result from os.times().\n\n\
7283This object may be accessed either as a tuple of\n\
7284 (user, system, children_user, children_system, elapsed),\n\
7285or via the attributes user, system, children_user, children_system,\n\
7286and elapsed.\n\
7287\n\
7288See os.times for more information.");
7289
7290static PyStructSequence_Desc times_result_desc = {
7291 "times_result", /* name */
7292 times_result__doc__, /* doc */
7293 times_result_fields,
7294 5
7295};
7296
7297static PyTypeObject TimesResultType;
7298
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007299#ifdef MS_WINDOWS
7300#define HAVE_TIMES /* mandatory, for the method table */
7301#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007302
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007303#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007304
7305static PyObject *
7306build_times_result(double user, double system,
7307 double children_user, double children_system,
7308 double elapsed)
7309{
7310 PyObject *value = PyStructSequence_New(&TimesResultType);
7311 if (value == NULL)
7312 return NULL;
7313
7314#define SET(i, field) \
7315 { \
7316 PyObject *o = PyFloat_FromDouble(field); \
7317 if (!o) { \
7318 Py_DECREF(value); \
7319 return NULL; \
7320 } \
7321 PyStructSequence_SET_ITEM(value, i, o); \
7322 } \
7323
7324 SET(0, user);
7325 SET(1, system);
7326 SET(2, children_user);
7327 SET(3, children_system);
7328 SET(4, elapsed);
7329
7330#undef SET
7331
7332 return value;
7333}
7334
7335PyDoc_STRVAR(posix_times__doc__,
7336"times() -> times_result\n\n\
7337Return an object containing floating point numbers indicating process\n\
7338times. The object behaves like a named tuple with these fields:\n\
7339 (utime, stime, cutime, cstime, elapsed_time)");
7340
Guido van Rossumd48f2521997-12-05 22:19:34 +00007341#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7342static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007343system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007344{
7345 ULONG value = 0;
7346
7347 Py_BEGIN_ALLOW_THREADS
7348 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7349 Py_END_ALLOW_THREADS
7350
7351 return value;
7352}
7353
7354static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007355posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007356{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007357 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007358 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007359 (double)0 /* t.tms_utime / HZ */,
7360 (double)0 /* t.tms_stime / HZ */,
7361 (double)0 /* t.tms_cutime / HZ */,
7362 (double)0 /* t.tms_cstime / HZ */,
7363 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007364}
Larry Hastings605a62d2012-06-24 04:33:36 -07007365#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007366static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007367posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007368{
Victor Stinner8c62be82010-05-06 00:08:46 +00007369 FILETIME create, exit, kernel, user;
7370 HANDLE hProc;
7371 hProc = GetCurrentProcess();
7372 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7373 /* The fields of a FILETIME structure are the hi and lo part
7374 of a 64-bit value expressed in 100 nanosecond units.
7375 1e7 is one second in such units; 1e-7 the inverse.
7376 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7377 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007378 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007379 (double)(user.dwHighDateTime*429.4967296 +
7380 user.dwLowDateTime*1e-7),
7381 (double)(kernel.dwHighDateTime*429.4967296 +
7382 kernel.dwLowDateTime*1e-7),
7383 (double)0,
7384 (double)0,
7385 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007386}
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007387#else /* Neither Windows nor OS/2 */
7388#define NEED_TICKS_PER_SECOND
7389static long ticks_per_second = -1;
7390static PyObject *
7391posix_times(PyObject *self, PyObject *noargs)
7392{
7393 struct tms t;
7394 clock_t c;
7395 errno = 0;
7396 c = times(&t);
7397 if (c == (clock_t) -1)
7398 return posix_error();
7399 return build_times_result(
7400 (double)t.tms_utime / ticks_per_second,
7401 (double)t.tms_stime / ticks_per_second,
7402 (double)t.tms_cutime / ticks_per_second,
7403 (double)t.tms_cstime / ticks_per_second,
7404 (double)c / ticks_per_second);
7405}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007406#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007407
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007408#endif /* HAVE_TIMES */
7409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007410
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007411#ifdef HAVE_GETSID
7412PyDoc_STRVAR(posix_getsid__doc__,
7413"getsid(pid) -> sid\n\n\
7414Call the system call getsid().");
7415
7416static PyObject *
7417posix_getsid(PyObject *self, PyObject *args)
7418{
Victor Stinner8c62be82010-05-06 00:08:46 +00007419 pid_t pid;
7420 int sid;
7421 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7422 return NULL;
7423 sid = getsid(pid);
7424 if (sid < 0)
7425 return posix_error();
7426 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007427}
7428#endif /* HAVE_GETSID */
7429
7430
Guido van Rossumb6775db1994-08-01 11:34:53 +00007431#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007432PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007433"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007434Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007435
Barry Warsaw53699e91996-12-10 23:23:01 +00007436static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007437posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007438{
Victor Stinner8c62be82010-05-06 00:08:46 +00007439 if (setsid() < 0)
7440 return posix_error();
7441 Py_INCREF(Py_None);
7442 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007443}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007444#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007445
Guido van Rossumb6775db1994-08-01 11:34:53 +00007446#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007447PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007448"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007449Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007450
Barry Warsaw53699e91996-12-10 23:23:01 +00007451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007452posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007453{
Victor Stinner8c62be82010-05-06 00:08:46 +00007454 pid_t pid;
7455 int pgrp;
7456 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7457 return NULL;
7458 if (setpgid(pid, pgrp) < 0)
7459 return posix_error();
7460 Py_INCREF(Py_None);
7461 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007462}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007463#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007465
Guido van Rossumb6775db1994-08-01 11:34:53 +00007466#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007467PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007468"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007469Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007470
Barry Warsaw53699e91996-12-10 23:23:01 +00007471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007472posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007473{
Victor Stinner8c62be82010-05-06 00:08:46 +00007474 int fd;
7475 pid_t pgid;
7476 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7477 return NULL;
7478 pgid = tcgetpgrp(fd);
7479 if (pgid < 0)
7480 return posix_error();
7481 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007482}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007483#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007484
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007485
Guido van Rossumb6775db1994-08-01 11:34:53 +00007486#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007487PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007488"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007489Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007490
Barry Warsaw53699e91996-12-10 23:23:01 +00007491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007492posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007493{
Victor Stinner8c62be82010-05-06 00:08:46 +00007494 int fd;
7495 pid_t pgid;
7496 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7497 return NULL;
7498 if (tcsetpgrp(fd, pgid) < 0)
7499 return posix_error();
7500 Py_INCREF(Py_None);
7501 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007502}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007503#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007504
Guido van Rossum687dd131993-05-17 08:34:16 +00007505/* Functions acting on file descriptors */
7506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007507PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007508"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7509Open a file for low level IO. Returns a file handle (integer).\n\
7510\n\
7511If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7512 and path should be relative; path will then be relative to that directory.\n\
7513dir_fd may not be implemented on your platform.\n\
7514 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007515
Barry Warsaw53699e91996-12-10 23:23:01 +00007516static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007517posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007518{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007519 path_t path;
7520 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007521 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007522 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007523 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007524 PyObject *return_value = NULL;
7525 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007526
Larry Hastings9cf065c2012-06-22 16:30:09 -07007527 memset(&path, 0, sizeof(path));
7528 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7529 path_converter, &path,
7530 &flags, &mode,
7531#ifdef HAVE_OPENAT
7532 dir_fd_converter, &dir_fd
7533#else
7534 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007535#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007536 ))
7537 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007538
Victor Stinner8c62be82010-05-06 00:08:46 +00007539 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007540#ifdef MS_WINDOWS
7541 if (path.wide)
7542 fd = _wopen(path.wide, flags, mode);
7543 else
7544#endif
7545#ifdef HAVE_OPENAT
7546 if (dir_fd != DEFAULT_DIR_FD)
7547 fd = openat(dir_fd, path.narrow, flags, mode);
7548 else
7549#endif
7550 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007551 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007552
Larry Hastings9cf065c2012-06-22 16:30:09 -07007553 if (fd == -1) {
7554#ifdef MS_WINDOWS
7555 /* force use of posix_error here for exact backwards compatibility */
7556 if (path.wide)
7557 return_value = posix_error();
7558 else
7559#endif
7560 return_value = path_error("open", &path);
7561 goto exit;
7562 }
7563
7564 return_value = PyLong_FromLong((long)fd);
7565
7566exit:
7567 path_cleanup(&path);
7568 return return_value;
7569}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007570
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007571PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007572"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007573Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007574
Barry Warsaw53699e91996-12-10 23:23:01 +00007575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007576posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007577{
Victor Stinner8c62be82010-05-06 00:08:46 +00007578 int fd, res;
7579 if (!PyArg_ParseTuple(args, "i:close", &fd))
7580 return NULL;
7581 if (!_PyVerify_fd(fd))
7582 return posix_error();
7583 Py_BEGIN_ALLOW_THREADS
7584 res = close(fd);
7585 Py_END_ALLOW_THREADS
7586 if (res < 0)
7587 return posix_error();
7588 Py_INCREF(Py_None);
7589 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007590}
7591
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007592
Victor Stinner8c62be82010-05-06 00:08:46 +00007593PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007594"closerange(fd_low, fd_high)\n\n\
7595Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7596
7597static PyObject *
7598posix_closerange(PyObject *self, PyObject *args)
7599{
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 int fd_from, fd_to, i;
7601 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7602 return NULL;
7603 Py_BEGIN_ALLOW_THREADS
7604 for (i = fd_from; i < fd_to; i++)
7605 if (_PyVerify_fd(i))
7606 close(i);
7607 Py_END_ALLOW_THREADS
7608 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007609}
7610
7611
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007612PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007613"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007614Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007615
Barry Warsaw53699e91996-12-10 23:23:01 +00007616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007617posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007618{
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 int fd;
7620 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7621 return NULL;
7622 if (!_PyVerify_fd(fd))
7623 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007624 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 if (fd < 0)
7626 return posix_error();
7627 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007628}
7629
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007630
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007631PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007632"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007633Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007634
Barry Warsaw53699e91996-12-10 23:23:01 +00007635static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007636posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007637{
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 int fd, fd2, res;
7639 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7640 return NULL;
7641 if (!_PyVerify_fd_dup2(fd, fd2))
7642 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007644 if (res < 0)
7645 return posix_error();
7646 Py_INCREF(Py_None);
7647 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007648}
7649
Ross Lagerwall7807c352011-03-17 20:20:30 +02007650#ifdef HAVE_LOCKF
7651PyDoc_STRVAR(posix_lockf__doc__,
7652"lockf(fd, cmd, len)\n\n\
7653Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7654fd is an open file descriptor.\n\
7655cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7656F_TEST.\n\
7657len specifies the section of the file to lock.");
7658
7659static PyObject *
7660posix_lockf(PyObject *self, PyObject *args)
7661{
7662 int fd, cmd, res;
7663 off_t len;
7664 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7665 &fd, &cmd, _parse_off_t, &len))
7666 return NULL;
7667
7668 Py_BEGIN_ALLOW_THREADS
7669 res = lockf(fd, cmd, len);
7670 Py_END_ALLOW_THREADS
7671
7672 if (res < 0)
7673 return posix_error();
7674
7675 Py_RETURN_NONE;
7676}
7677#endif
7678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007680PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007681"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007682Set the current position of a file descriptor.\n\
7683Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007684
Barry Warsaw53699e91996-12-10 23:23:01 +00007685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007686posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007687{
Victor Stinner8c62be82010-05-06 00:08:46 +00007688 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007689#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007690 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007691#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007692 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007693#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007694 PyObject *posobj;
7695 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007696 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007697#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7699 switch (how) {
7700 case 0: how = SEEK_SET; break;
7701 case 1: how = SEEK_CUR; break;
7702 case 2: how = SEEK_END; break;
7703 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007704#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007705
Ross Lagerwall8e749672011-03-17 21:54:07 +02007706#if !defined(HAVE_LARGEFILE_SUPPORT)
7707 pos = PyLong_AsLong(posobj);
7708#else
7709 pos = PyLong_AsLongLong(posobj);
7710#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 if (PyErr_Occurred())
7712 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007713
Victor Stinner8c62be82010-05-06 00:08:46 +00007714 if (!_PyVerify_fd(fd))
7715 return posix_error();
7716 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007717#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007718 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007719#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007720 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007721#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 Py_END_ALLOW_THREADS
7723 if (res < 0)
7724 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007725
7726#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007728#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007730#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007731}
7732
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007733
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007734PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007735"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007736Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007737
Barry Warsaw53699e91996-12-10 23:23:01 +00007738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007739posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007740{
Victor Stinner8c62be82010-05-06 00:08:46 +00007741 int fd, size;
7742 Py_ssize_t n;
7743 PyObject *buffer;
7744 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7745 return NULL;
7746 if (size < 0) {
7747 errno = EINVAL;
7748 return posix_error();
7749 }
7750 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7751 if (buffer == NULL)
7752 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007753 if (!_PyVerify_fd(fd)) {
7754 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007756 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007757 Py_BEGIN_ALLOW_THREADS
7758 n = read(fd, PyBytes_AS_STRING(buffer), size);
7759 Py_END_ALLOW_THREADS
7760 if (n < 0) {
7761 Py_DECREF(buffer);
7762 return posix_error();
7763 }
7764 if (n != size)
7765 _PyBytes_Resize(&buffer, n);
7766 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007767}
7768
Ross Lagerwall7807c352011-03-17 20:20:30 +02007769#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7770 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007771static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007772iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7773{
7774 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007775 Py_ssize_t blen, total = 0;
7776
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007777 *iov = PyMem_New(struct iovec, cnt);
7778 if (*iov == NULL) {
7779 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007780 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007781 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007782
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007783 *buf = PyMem_New(Py_buffer, cnt);
7784 if (*buf == NULL) {
7785 PyMem_Del(*iov);
7786 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007787 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007788 }
7789
7790 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007791 PyObject *item = PySequence_GetItem(seq, i);
7792 if (item == NULL)
7793 goto fail;
7794 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7795 Py_DECREF(item);
7796 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007797 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007798 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007799 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007800 blen = (*buf)[i].len;
7801 (*iov)[i].iov_len = blen;
7802 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007803 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007804 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007805
7806fail:
7807 PyMem_Del(*iov);
7808 for (j = 0; j < i; j++) {
7809 PyBuffer_Release(&(*buf)[j]);
7810 }
7811 PyMem_Del(*buf);
7812 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007813}
7814
7815static void
7816iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7817{
7818 int i;
7819 PyMem_Del(iov);
7820 for (i = 0; i < cnt; i++) {
7821 PyBuffer_Release(&buf[i]);
7822 }
7823 PyMem_Del(buf);
7824}
7825#endif
7826
Ross Lagerwall7807c352011-03-17 20:20:30 +02007827#ifdef HAVE_READV
7828PyDoc_STRVAR(posix_readv__doc__,
7829"readv(fd, buffers) -> bytesread\n\n\
7830Read from a file descriptor into a number of writable buffers. buffers\n\
7831is an arbitrary sequence of writable buffers.\n\
7832Returns the total number of bytes read.");
7833
7834static PyObject *
7835posix_readv(PyObject *self, PyObject *args)
7836{
7837 int fd, cnt;
7838 Py_ssize_t n;
7839 PyObject *seq;
7840 struct iovec *iov;
7841 Py_buffer *buf;
7842
7843 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7844 return NULL;
7845 if (!PySequence_Check(seq)) {
7846 PyErr_SetString(PyExc_TypeError,
7847 "readv() arg 2 must be a sequence");
7848 return NULL;
7849 }
7850 cnt = PySequence_Size(seq);
7851
7852 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7853 return NULL;
7854
7855 Py_BEGIN_ALLOW_THREADS
7856 n = readv(fd, iov, cnt);
7857 Py_END_ALLOW_THREADS
7858
7859 iov_cleanup(iov, buf, cnt);
7860 return PyLong_FromSsize_t(n);
7861}
7862#endif
7863
7864#ifdef HAVE_PREAD
7865PyDoc_STRVAR(posix_pread__doc__,
7866"pread(fd, buffersize, offset) -> string\n\n\
7867Read from a file descriptor, fd, at a position of offset. It will read up\n\
7868to buffersize number of bytes. The file offset remains unchanged.");
7869
7870static PyObject *
7871posix_pread(PyObject *self, PyObject *args)
7872{
7873 int fd, size;
7874 off_t offset;
7875 Py_ssize_t n;
7876 PyObject *buffer;
7877 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7878 return NULL;
7879
7880 if (size < 0) {
7881 errno = EINVAL;
7882 return posix_error();
7883 }
7884 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7885 if (buffer == NULL)
7886 return NULL;
7887 if (!_PyVerify_fd(fd)) {
7888 Py_DECREF(buffer);
7889 return posix_error();
7890 }
7891 Py_BEGIN_ALLOW_THREADS
7892 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7893 Py_END_ALLOW_THREADS
7894 if (n < 0) {
7895 Py_DECREF(buffer);
7896 return posix_error();
7897 }
7898 if (n != size)
7899 _PyBytes_Resize(&buffer, n);
7900 return buffer;
7901}
7902#endif
7903
7904PyDoc_STRVAR(posix_write__doc__,
7905"write(fd, string) -> byteswritten\n\n\
7906Write a string to a file descriptor.");
7907
7908static PyObject *
7909posix_write(PyObject *self, PyObject *args)
7910{
7911 Py_buffer pbuf;
7912 int fd;
7913 Py_ssize_t size, len;
7914
7915 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7916 return NULL;
7917 if (!_PyVerify_fd(fd)) {
7918 PyBuffer_Release(&pbuf);
7919 return posix_error();
7920 }
7921 len = pbuf.len;
7922 Py_BEGIN_ALLOW_THREADS
7923#if defined(MS_WIN64) || defined(MS_WINDOWS)
7924 if (len > INT_MAX)
7925 len = INT_MAX;
7926 size = write(fd, pbuf.buf, (int)len);
7927#else
7928 size = write(fd, pbuf.buf, len);
7929#endif
7930 Py_END_ALLOW_THREADS
7931 PyBuffer_Release(&pbuf);
7932 if (size < 0)
7933 return posix_error();
7934 return PyLong_FromSsize_t(size);
7935}
7936
7937#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007938PyDoc_STRVAR(posix_sendfile__doc__,
7939"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7940sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7941 -> byteswritten\n\
7942Copy nbytes bytes from file descriptor in to file descriptor out.");
7943
7944static PyObject *
7945posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7946{
7947 int in, out;
7948 Py_ssize_t ret;
7949 off_t offset;
7950
7951#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7952#ifndef __APPLE__
7953 Py_ssize_t len;
7954#endif
7955 PyObject *headers = NULL, *trailers = NULL;
7956 Py_buffer *hbuf, *tbuf;
7957 off_t sbytes;
7958 struct sf_hdtr sf;
7959 int flags = 0;
7960 sf.headers = NULL;
7961 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007962 static char *keywords[] = {"out", "in",
7963 "offset", "count",
7964 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007965
7966#ifdef __APPLE__
7967 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007968 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007969#else
7970 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007971 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007972#endif
7973 &headers, &trailers, &flags))
7974 return NULL;
7975 if (headers != NULL) {
7976 if (!PySequence_Check(headers)) {
7977 PyErr_SetString(PyExc_TypeError,
7978 "sendfile() headers must be a sequence or None");
7979 return NULL;
7980 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007981 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007982 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007983 if (sf.hdr_cnt > 0 &&
7984 !(i = iov_setup(&(sf.headers), &hbuf,
7985 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007986 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007987#ifdef __APPLE__
7988 sbytes += i;
7989#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007990 }
7991 }
7992 if (trailers != NULL) {
7993 if (!PySequence_Check(trailers)) {
7994 PyErr_SetString(PyExc_TypeError,
7995 "sendfile() trailers must be a sequence or None");
7996 return NULL;
7997 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007998 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007999 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008000 if (sf.trl_cnt > 0 &&
8001 !(i = iov_setup(&(sf.trailers), &tbuf,
8002 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008003 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008004#ifdef __APPLE__
8005 sbytes += i;
8006#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008007 }
8008 }
8009
8010 Py_BEGIN_ALLOW_THREADS
8011#ifdef __APPLE__
8012 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8013#else
8014 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8015#endif
8016 Py_END_ALLOW_THREADS
8017
8018 if (sf.headers != NULL)
8019 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8020 if (sf.trailers != NULL)
8021 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8022
8023 if (ret < 0) {
8024 if ((errno == EAGAIN) || (errno == EBUSY)) {
8025 if (sbytes != 0) {
8026 // some data has been sent
8027 goto done;
8028 }
8029 else {
8030 // no data has been sent; upper application is supposed
8031 // to retry on EAGAIN or EBUSY
8032 return posix_error();
8033 }
8034 }
8035 return posix_error();
8036 }
8037 goto done;
8038
8039done:
8040 #if !defined(HAVE_LARGEFILE_SUPPORT)
8041 return Py_BuildValue("l", sbytes);
8042 #else
8043 return Py_BuildValue("L", sbytes);
8044 #endif
8045
8046#else
8047 Py_ssize_t count;
8048 PyObject *offobj;
8049 static char *keywords[] = {"out", "in",
8050 "offset", "count", NULL};
8051 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8052 keywords, &out, &in, &offobj, &count))
8053 return NULL;
8054#ifdef linux
8055 if (offobj == Py_None) {
8056 Py_BEGIN_ALLOW_THREADS
8057 ret = sendfile(out, in, NULL, count);
8058 Py_END_ALLOW_THREADS
8059 if (ret < 0)
8060 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008061 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008062 }
8063#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008064 if (!_parse_off_t(offobj, &offset))
8065 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066 Py_BEGIN_ALLOW_THREADS
8067 ret = sendfile(out, in, &offset, count);
8068 Py_END_ALLOW_THREADS
8069 if (ret < 0)
8070 return posix_error();
8071 return Py_BuildValue("n", ret);
8072#endif
8073}
8074#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008075
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008076PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008077"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008078Like stat(), but for an open file descriptor.\n\
8079Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008080
Barry Warsaw53699e91996-12-10 23:23:01 +00008081static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008082posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008083{
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 int fd;
8085 STRUCT_STAT st;
8086 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008087 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008089#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008090 /* on OpenVMS we must ensure that all bytes are written to the file */
8091 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008092#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008093 Py_BEGIN_ALLOW_THREADS
8094 res = FSTAT(fd, &st);
8095 Py_END_ALLOW_THREADS
8096 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008097#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008098 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008099#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008101#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008102 }
Tim Peters5aa91602002-01-30 05:46:57 +00008103
Victor Stinner4195b5c2012-02-08 23:03:19 +01008104 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008105}
8106
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008107PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008108"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008109Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008110connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008111
8112static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008113posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008114{
Victor Stinner8c62be82010-05-06 00:08:46 +00008115 int fd;
8116 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8117 return NULL;
8118 if (!_PyVerify_fd(fd))
8119 return PyBool_FromLong(0);
8120 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008121}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008122
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008123#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008124PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008125"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008126Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008127
Barry Warsaw53699e91996-12-10 23:23:01 +00008128static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008129posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008130{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008131#if defined(PYOS_OS2)
8132 HFILE read, write;
8133 APIRET rc;
8134
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008135 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008136 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008137 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008138
8139 return Py_BuildValue("(ii)", read, write);
8140#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008141#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 int fds[2];
8143 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008144 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008145 if (res != 0)
8146 return posix_error();
8147 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008148#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008149 HANDLE read, write;
8150 int read_fd, write_fd;
8151 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008153 if (!ok)
8154 return win32_error("CreatePipe", NULL);
8155 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8156 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8157 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008158#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008159#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008160}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008161#endif /* HAVE_PIPE */
8162
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008163#ifdef HAVE_PIPE2
8164PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008165"pipe2(flags) -> (read_end, write_end)\n\n\
8166Create a pipe with flags set atomically.\n\
8167flags can be constructed by ORing together one or more of these values:\n\
8168O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008169");
8170
8171static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008172posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008173{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008174 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008175 int fds[2];
8176 int res;
8177
Serhiy Storchaka9101e232013-01-19 12:41:45 +02008178 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008179 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008180 return NULL;
8181
8182 res = pipe2(fds, flags);
8183 if (res != 0)
8184 return posix_error();
8185 return Py_BuildValue("(ii)", fds[0], fds[1]);
8186}
8187#endif /* HAVE_PIPE2 */
8188
Ross Lagerwall7807c352011-03-17 20:20:30 +02008189#ifdef HAVE_WRITEV
8190PyDoc_STRVAR(posix_writev__doc__,
8191"writev(fd, buffers) -> byteswritten\n\n\
8192Write the contents of buffers to a file descriptor, where buffers is an\n\
8193arbitrary sequence of buffers.\n\
8194Returns the total bytes written.");
8195
8196static PyObject *
8197posix_writev(PyObject *self, PyObject *args)
8198{
8199 int fd, cnt;
8200 Py_ssize_t res;
8201 PyObject *seq;
8202 struct iovec *iov;
8203 Py_buffer *buf;
8204 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8205 return NULL;
8206 if (!PySequence_Check(seq)) {
8207 PyErr_SetString(PyExc_TypeError,
8208 "writev() arg 2 must be a sequence");
8209 return NULL;
8210 }
8211 cnt = PySequence_Size(seq);
8212
8213 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8214 return NULL;
8215 }
8216
8217 Py_BEGIN_ALLOW_THREADS
8218 res = writev(fd, iov, cnt);
8219 Py_END_ALLOW_THREADS
8220
8221 iov_cleanup(iov, buf, cnt);
8222 return PyLong_FromSsize_t(res);
8223}
8224#endif
8225
8226#ifdef HAVE_PWRITE
8227PyDoc_STRVAR(posix_pwrite__doc__,
8228"pwrite(fd, string, offset) -> byteswritten\n\n\
8229Write string to a file descriptor, fd, from offset, leaving the file\n\
8230offset unchanged.");
8231
8232static PyObject *
8233posix_pwrite(PyObject *self, PyObject *args)
8234{
8235 Py_buffer pbuf;
8236 int fd;
8237 off_t offset;
8238 Py_ssize_t size;
8239
8240 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8241 return NULL;
8242
8243 if (!_PyVerify_fd(fd)) {
8244 PyBuffer_Release(&pbuf);
8245 return posix_error();
8246 }
8247 Py_BEGIN_ALLOW_THREADS
8248 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8249 Py_END_ALLOW_THREADS
8250 PyBuffer_Release(&pbuf);
8251 if (size < 0)
8252 return posix_error();
8253 return PyLong_FromSsize_t(size);
8254}
8255#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008256
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008257#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008258PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008259"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8260Create a FIFO (a POSIX named pipe).\n\
8261\n\
8262If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8263 and path should be relative; path will then be relative to that directory.\n\
8264dir_fd may not be implemented on your platform.\n\
8265 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008266
Barry Warsaw53699e91996-12-10 23:23:01 +00008267static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008268posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008269{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008270 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008271 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008272 int dir_fd = DEFAULT_DIR_FD;
8273 int result;
8274 PyObject *return_value = NULL;
8275 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8276
8277 memset(&path, 0, sizeof(path));
8278 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8279 path_converter, &path,
8280 &mode,
8281#ifdef HAVE_MKFIFOAT
8282 dir_fd_converter, &dir_fd
8283#else
8284 dir_fd_unavailable, &dir_fd
8285#endif
8286 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008287 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008288
Victor Stinner8c62be82010-05-06 00:08:46 +00008289 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008290#ifdef HAVE_MKFIFOAT
8291 if (dir_fd != DEFAULT_DIR_FD)
8292 result = mkfifoat(dir_fd, path.narrow, mode);
8293 else
8294#endif
8295 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008297
8298 if (result < 0) {
8299 return_value = posix_error();
8300 goto exit;
8301 }
8302
8303 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008304 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008305
8306exit:
8307 path_cleanup(&path);
8308 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008309}
8310#endif
8311
Neal Norwitz11690112002-07-30 01:08:28 +00008312#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008313PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008314"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008315Create a filesystem node (file, device special file or named pipe)\n\
8316named filename. mode specifies both the permissions to use and the\n\
8317type of node to be created, being combined (bitwise OR) with one of\n\
8318S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008319device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008320os.makedev()), otherwise it is ignored.\n\
8321\n\
8322If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8323 and path should be relative; path will then be relative to that directory.\n\
8324dir_fd may not be implemented on your platform.\n\
8325 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008326
8327
8328static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008329posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008330{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008331 path_t path;
8332 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008333 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008334 int dir_fd = DEFAULT_DIR_FD;
8335 int result;
8336 PyObject *return_value = NULL;
8337 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8338
8339 memset(&path, 0, sizeof(path));
8340 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8341 path_converter, &path,
8342 &mode, &device,
8343#ifdef HAVE_MKNODAT
8344 dir_fd_converter, &dir_fd
8345#else
8346 dir_fd_unavailable, &dir_fd
8347#endif
8348 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008349 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008350
Victor Stinner8c62be82010-05-06 00:08:46 +00008351 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008352#ifdef HAVE_MKNODAT
8353 if (dir_fd != DEFAULT_DIR_FD)
8354 result = mknodat(dir_fd, path.narrow, mode, device);
8355 else
8356#endif
8357 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008358 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008359
8360 if (result < 0) {
8361 return_value = posix_error();
8362 goto exit;
8363 }
8364
8365 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008367
Larry Hastings9cf065c2012-06-22 16:30:09 -07008368exit:
8369 path_cleanup(&path);
8370 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008371}
8372#endif
8373
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008374#ifdef HAVE_DEVICE_MACROS
8375PyDoc_STRVAR(posix_major__doc__,
8376"major(device) -> major number\n\
8377Extracts a device major number from a raw device number.");
8378
8379static PyObject *
8380posix_major(PyObject *self, PyObject *args)
8381{
Victor Stinner8c62be82010-05-06 00:08:46 +00008382 int device;
8383 if (!PyArg_ParseTuple(args, "i:major", &device))
8384 return NULL;
8385 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008386}
8387
8388PyDoc_STRVAR(posix_minor__doc__,
8389"minor(device) -> minor number\n\
8390Extracts a device minor number from a raw device number.");
8391
8392static PyObject *
8393posix_minor(PyObject *self, PyObject *args)
8394{
Victor Stinner8c62be82010-05-06 00:08:46 +00008395 int device;
8396 if (!PyArg_ParseTuple(args, "i:minor", &device))
8397 return NULL;
8398 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008399}
8400
8401PyDoc_STRVAR(posix_makedev__doc__,
8402"makedev(major, minor) -> device number\n\
8403Composes a raw device number from the major and minor device numbers.");
8404
8405static PyObject *
8406posix_makedev(PyObject *self, PyObject *args)
8407{
Victor Stinner8c62be82010-05-06 00:08:46 +00008408 int major, minor;
8409 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8410 return NULL;
8411 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008412}
8413#endif /* device macros */
8414
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008415
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008416#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008417PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008418"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008419Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008420
Barry Warsaw53699e91996-12-10 23:23:01 +00008421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008422posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008423{
Victor Stinner8c62be82010-05-06 00:08:46 +00008424 int fd;
8425 off_t length;
8426 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008427
Ross Lagerwall7807c352011-03-17 20:20:30 +02008428 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008429 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008430
Victor Stinner8c62be82010-05-06 00:08:46 +00008431 Py_BEGIN_ALLOW_THREADS
8432 res = ftruncate(fd, length);
8433 Py_END_ALLOW_THREADS
8434 if (res < 0)
8435 return posix_error();
8436 Py_INCREF(Py_None);
8437 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008438}
8439#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008440
Ross Lagerwall7807c352011-03-17 20:20:30 +02008441#ifdef HAVE_TRUNCATE
8442PyDoc_STRVAR(posix_truncate__doc__,
8443"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008444Truncate the file given by path to length bytes.\n\
8445On some platforms, path may also be specified as an open file descriptor.\n\
8446 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008447
8448static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008449posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008450{
Georg Brandl306336b2012-06-24 12:55:33 +02008451 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008452 off_t length;
8453 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008454 PyObject *result = NULL;
8455 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008456
Georg Brandl306336b2012-06-24 12:55:33 +02008457 memset(&path, 0, sizeof(path));
8458#ifdef HAVE_FTRUNCATE
8459 path.allow_fd = 1;
8460#endif
8461 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8462 path_converter, &path,
8463 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008464 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008465
8466 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008467#ifdef HAVE_FTRUNCATE
8468 if (path.fd != -1)
8469 res = ftruncate(path.fd, length);
8470 else
8471#endif
8472 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008473 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008474 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008475 result = path_posix_error("truncate", &path);
8476 else {
8477 Py_INCREF(Py_None);
8478 result = Py_None;
8479 }
8480 path_cleanup(&path);
8481 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008482}
8483#endif
8484
8485#ifdef HAVE_POSIX_FALLOCATE
8486PyDoc_STRVAR(posix_posix_fallocate__doc__,
8487"posix_fallocate(fd, offset, len)\n\n\
8488Ensures that enough disk space is allocated for the file specified by fd\n\
8489starting from offset and continuing for len bytes.");
8490
8491static PyObject *
8492posix_posix_fallocate(PyObject *self, PyObject *args)
8493{
8494 off_t len, offset;
8495 int res, fd;
8496
8497 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8498 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8499 return NULL;
8500
8501 Py_BEGIN_ALLOW_THREADS
8502 res = posix_fallocate(fd, offset, len);
8503 Py_END_ALLOW_THREADS
8504 if (res != 0) {
8505 errno = res;
8506 return posix_error();
8507 }
8508 Py_RETURN_NONE;
8509}
8510#endif
8511
8512#ifdef HAVE_POSIX_FADVISE
8513PyDoc_STRVAR(posix_posix_fadvise__doc__,
8514"posix_fadvise(fd, offset, len, advice)\n\n\
8515Announces an intention to access data in a specific pattern thus allowing\n\
8516the kernel to make optimizations.\n\
8517The advice applies to the region of the file specified by fd starting at\n\
8518offset and continuing for len bytes.\n\
8519advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8520POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8521POSIX_FADV_DONTNEED.");
8522
8523static PyObject *
8524posix_posix_fadvise(PyObject *self, PyObject *args)
8525{
8526 off_t len, offset;
8527 int res, fd, advice;
8528
8529 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8530 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8531 return NULL;
8532
8533 Py_BEGIN_ALLOW_THREADS
8534 res = posix_fadvise(fd, offset, len, advice);
8535 Py_END_ALLOW_THREADS
8536 if (res != 0) {
8537 errno = res;
8538 return posix_error();
8539 }
8540 Py_RETURN_NONE;
8541}
8542#endif
8543
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008544#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008545PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008546"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008547Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008548
Fred Drake762e2061999-08-26 17:23:54 +00008549/* Save putenv() parameters as values here, so we can collect them when they
8550 * get re-set with another call for the same key. */
8551static PyObject *posix_putenv_garbage;
8552
Tim Peters5aa91602002-01-30 05:46:57 +00008553static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008554posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008555{
Victor Stinner84ae1182010-05-06 22:05:07 +00008556 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008557#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008558 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008559 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008560
Victor Stinner8c62be82010-05-06 00:08:46 +00008561 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008562 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008563 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008564 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008565
Victor Stinner65170952011-11-22 22:16:17 +01008566 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008567 if (newstr == NULL) {
8568 PyErr_NoMemory();
8569 goto error;
8570 }
Victor Stinner65170952011-11-22 22:16:17 +01008571 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8572 PyErr_Format(PyExc_ValueError,
8573 "the environment variable is longer than %u characters",
8574 _MAX_ENV);
8575 goto error;
8576 }
8577
Victor Stinner8c62be82010-05-06 00:08:46 +00008578 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008579 if (newenv == NULL)
8580 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008581 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008582 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008583 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008584 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008585#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008586 PyObject *os1, *os2;
8587 char *s1, *s2;
8588 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008589
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008590 if (!PyArg_ParseTuple(args,
8591 "O&O&:putenv",
8592 PyUnicode_FSConverter, &os1,
8593 PyUnicode_FSConverter, &os2))
8594 return NULL;
8595 s1 = PyBytes_AsString(os1);
8596 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008597
Victor Stinner65170952011-11-22 22:16:17 +01008598 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008599 if (newstr == NULL) {
8600 PyErr_NoMemory();
8601 goto error;
8602 }
8603
Victor Stinner8c62be82010-05-06 00:08:46 +00008604 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008605 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008606 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008607 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008608 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008609#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008610
Victor Stinner8c62be82010-05-06 00:08:46 +00008611 /* Install the first arg and newstr in posix_putenv_garbage;
8612 * this will cause previous value to be collected. This has to
8613 * happen after the real putenv() call because the old value
8614 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008615 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008616 /* really not much we can do; just leak */
8617 PyErr_Clear();
8618 }
8619 else {
8620 Py_DECREF(newstr);
8621 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008622
Martin v. Löwis011e8422009-05-05 04:43:17 +00008623#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008624 Py_DECREF(os1);
8625 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008626#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008627 Py_RETURN_NONE;
8628
8629error:
8630#ifndef MS_WINDOWS
8631 Py_DECREF(os1);
8632 Py_DECREF(os2);
8633#endif
8634 Py_XDECREF(newstr);
8635 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008636}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008637#endif /* putenv */
8638
Guido van Rossumc524d952001-10-19 01:31:59 +00008639#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008640PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008641"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008642Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008643
8644static PyObject *
8645posix_unsetenv(PyObject *self, PyObject *args)
8646{
Victor Stinner65170952011-11-22 22:16:17 +01008647 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008648#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008649 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008650#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008651
8652 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008653
Victor Stinner65170952011-11-22 22:16:17 +01008654 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008655 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008656
Victor Stinner984890f2011-11-24 13:53:38 +01008657#ifdef HAVE_BROKEN_UNSETENV
8658 unsetenv(PyBytes_AS_STRING(name));
8659#else
Victor Stinner65170952011-11-22 22:16:17 +01008660 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008661 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008662 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008663 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008664 }
Victor Stinner984890f2011-11-24 13:53:38 +01008665#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008666
Victor Stinner8c62be82010-05-06 00:08:46 +00008667 /* Remove the key from posix_putenv_garbage;
8668 * this will cause it to be collected. This has to
8669 * happen after the real unsetenv() call because the
8670 * old value was still accessible until then.
8671 */
Victor Stinner65170952011-11-22 22:16:17 +01008672 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008673 /* really not much we can do; just leak */
8674 PyErr_Clear();
8675 }
Victor Stinner65170952011-11-22 22:16:17 +01008676 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008677 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008678}
8679#endif /* unsetenv */
8680
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008681PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008682"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008683Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008684
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008686posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008687{
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 int code;
8689 char *message;
8690 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8691 return NULL;
8692 message = strerror(code);
8693 if (message == NULL) {
8694 PyErr_SetString(PyExc_ValueError,
8695 "strerror() argument out of range");
8696 return NULL;
8697 }
Victor Stinner1b579672011-12-17 05:47:23 +01008698 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008699}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008700
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008701
Guido van Rossumc9641791998-08-04 15:26:23 +00008702#ifdef HAVE_SYS_WAIT_H
8703
Fred Drake106c1a02002-04-23 15:58:02 +00008704#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008705PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008706"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008707Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008708
8709static PyObject *
8710posix_WCOREDUMP(PyObject *self, PyObject *args)
8711{
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 WAIT_TYPE status;
8713 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008714
Victor Stinner8c62be82010-05-06 00:08:46 +00008715 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8716 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008717
Victor Stinner8c62be82010-05-06 00:08:46 +00008718 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008719}
8720#endif /* WCOREDUMP */
8721
8722#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008723PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008724"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008725Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008726job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008727
8728static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008729posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008730{
Victor Stinner8c62be82010-05-06 00:08:46 +00008731 WAIT_TYPE status;
8732 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008733
Victor Stinner8c62be82010-05-06 00:08:46 +00008734 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8735 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008736
Victor Stinner8c62be82010-05-06 00:08:46 +00008737 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008738}
8739#endif /* WIFCONTINUED */
8740
Guido van Rossumc9641791998-08-04 15:26:23 +00008741#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008742PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008743"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008744Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008745
8746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008747posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008748{
Victor Stinner8c62be82010-05-06 00:08:46 +00008749 WAIT_TYPE status;
8750 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008751
Victor Stinner8c62be82010-05-06 00:08:46 +00008752 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8753 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008754
Victor Stinner8c62be82010-05-06 00:08:46 +00008755 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008756}
8757#endif /* WIFSTOPPED */
8758
8759#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008760PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008761"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008762Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008763
8764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008765posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008766{
Victor Stinner8c62be82010-05-06 00:08:46 +00008767 WAIT_TYPE status;
8768 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008769
Victor Stinner8c62be82010-05-06 00:08:46 +00008770 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8771 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008772
Victor Stinner8c62be82010-05-06 00:08:46 +00008773 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008774}
8775#endif /* WIFSIGNALED */
8776
8777#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008778PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008779"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008780Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008781system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008782
8783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008784posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008785{
Victor Stinner8c62be82010-05-06 00:08:46 +00008786 WAIT_TYPE status;
8787 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008788
Victor Stinner8c62be82010-05-06 00:08:46 +00008789 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8790 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008791
Victor Stinner8c62be82010-05-06 00:08:46 +00008792 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008793}
8794#endif /* WIFEXITED */
8795
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008796#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008797PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008798"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008799Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008800
8801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008802posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008803{
Victor Stinner8c62be82010-05-06 00:08:46 +00008804 WAIT_TYPE status;
8805 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008806
Victor Stinner8c62be82010-05-06 00:08:46 +00008807 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8808 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008809
Victor Stinner8c62be82010-05-06 00:08:46 +00008810 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008811}
8812#endif /* WEXITSTATUS */
8813
8814#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008815PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008816"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008817Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008818value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008819
8820static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008821posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008822{
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 WAIT_TYPE status;
8824 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008825
Victor Stinner8c62be82010-05-06 00:08:46 +00008826 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8827 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008828
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008830}
8831#endif /* WTERMSIG */
8832
8833#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008834PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008835"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008836Return the signal that stopped the process that provided\n\
8837the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008838
8839static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008840posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008841{
Victor Stinner8c62be82010-05-06 00:08:46 +00008842 WAIT_TYPE status;
8843 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008844
Victor Stinner8c62be82010-05-06 00:08:46 +00008845 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8846 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008847
Victor Stinner8c62be82010-05-06 00:08:46 +00008848 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008849}
8850#endif /* WSTOPSIG */
8851
8852#endif /* HAVE_SYS_WAIT_H */
8853
8854
Thomas Wouters477c8d52006-05-27 19:21:47 +00008855#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008856#ifdef _SCO_DS
8857/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8858 needed definitions in sys/statvfs.h */
8859#define _SVID3
8860#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008861#include <sys/statvfs.h>
8862
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008863static PyObject*
8864_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8866 if (v == NULL)
8867 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008868
8869#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008870 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8871 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8872 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8873 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8874 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8875 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8876 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8877 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8878 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8879 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008880#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008881 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8882 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8883 PyStructSequence_SET_ITEM(v, 2,
8884 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8885 PyStructSequence_SET_ITEM(v, 3,
8886 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8887 PyStructSequence_SET_ITEM(v, 4,
8888 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8889 PyStructSequence_SET_ITEM(v, 5,
8890 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8891 PyStructSequence_SET_ITEM(v, 6,
8892 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8893 PyStructSequence_SET_ITEM(v, 7,
8894 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8895 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8896 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008897#endif
8898
Victor Stinner8c62be82010-05-06 00:08:46 +00008899 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008900}
8901
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008902PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008903"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008904Perform an fstatvfs system call on the given fd.\n\
8905Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008906
8907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008908posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008909{
Victor Stinner8c62be82010-05-06 00:08:46 +00008910 int fd, res;
8911 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008912
Victor Stinner8c62be82010-05-06 00:08:46 +00008913 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8914 return NULL;
8915 Py_BEGIN_ALLOW_THREADS
8916 res = fstatvfs(fd, &st);
8917 Py_END_ALLOW_THREADS
8918 if (res != 0)
8919 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008920
Victor Stinner8c62be82010-05-06 00:08:46 +00008921 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008922}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008923#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008924
8925
Thomas Wouters477c8d52006-05-27 19:21:47 +00008926#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008927#include <sys/statvfs.h>
8928
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008929PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008930"statvfs(path)\n\n\
8931Perform a statvfs system call on the given path.\n\
8932\n\
8933path may always be specified as a string.\n\
8934On some platforms, path may also be specified as an open file descriptor.\n\
8935 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008936
8937static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008938posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008939{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008940 static char *keywords[] = {"path", NULL};
8941 path_t path;
8942 int result;
8943 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008944 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008945
Larry Hastings9cf065c2012-06-22 16:30:09 -07008946 memset(&path, 0, sizeof(path));
8947#ifdef HAVE_FSTATVFS
8948 path.allow_fd = 1;
8949#endif
8950 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8951 path_converter, &path
8952 ))
8953 return NULL;
8954
8955 Py_BEGIN_ALLOW_THREADS
8956#ifdef HAVE_FSTATVFS
8957 if (path.fd != -1) {
8958#ifdef __APPLE__
8959 /* handle weak-linking on Mac OS X 10.3 */
8960 if (fstatvfs == NULL) {
8961 fd_specified("statvfs", path.fd);
8962 goto exit;
8963 }
8964#endif
8965 result = fstatvfs(path.fd, &st);
8966 }
8967 else
8968#endif
8969 result = statvfs(path.narrow, &st);
8970 Py_END_ALLOW_THREADS
8971
8972 if (result) {
8973 return_value = path_posix_error("statvfs", &path);
8974 goto exit;
8975 }
8976
8977 return_value = _pystatvfs_fromstructstatvfs(st);
8978
8979exit:
8980 path_cleanup(&path);
8981 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008982}
8983#endif /* HAVE_STATVFS */
8984
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008985#ifdef MS_WINDOWS
8986PyDoc_STRVAR(win32__getdiskusage__doc__,
8987"_getdiskusage(path) -> (total, free)\n\n\
8988Return disk usage statistics about the given path as (total, free) tuple.");
8989
8990static PyObject *
8991win32__getdiskusage(PyObject *self, PyObject *args)
8992{
8993 BOOL retval;
8994 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008995 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008996
Victor Stinner6139c1b2011-11-09 22:14:14 +01008997 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008998 return NULL;
8999
9000 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009001 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009002 Py_END_ALLOW_THREADS
9003 if (retval == 0)
9004 return PyErr_SetFromWindowsErr(0);
9005
9006 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9007}
9008#endif
9009
9010
Fred Drakec9680921999-12-13 16:37:25 +00009011/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9012 * It maps strings representing configuration variable names to
9013 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009014 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009015 * rarely-used constants. There are three separate tables that use
9016 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009017 *
9018 * This code is always included, even if none of the interfaces that
9019 * need it are included. The #if hackery needed to avoid it would be
9020 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009021 */
9022struct constdef {
9023 char *name;
9024 long value;
9025};
9026
Fred Drake12c6e2d1999-12-14 21:25:03 +00009027static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009028conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009029 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009030{
Christian Heimes217cfd12007-12-02 14:31:20 +00009031 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009032 *valuep = PyLong_AS_LONG(arg);
9033 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009034 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009035 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009036 /* look up the value in the table using a binary search */
9037 size_t lo = 0;
9038 size_t mid;
9039 size_t hi = tablesize;
9040 int cmp;
9041 const char *confname;
9042 if (!PyUnicode_Check(arg)) {
9043 PyErr_SetString(PyExc_TypeError,
9044 "configuration names must be strings or integers");
9045 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009046 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009047 confname = _PyUnicode_AsString(arg);
9048 if (confname == NULL)
9049 return 0;
9050 while (lo < hi) {
9051 mid = (lo + hi) / 2;
9052 cmp = strcmp(confname, table[mid].name);
9053 if (cmp < 0)
9054 hi = mid;
9055 else if (cmp > 0)
9056 lo = mid + 1;
9057 else {
9058 *valuep = table[mid].value;
9059 return 1;
9060 }
9061 }
9062 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9063 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009064 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009065}
9066
9067
9068#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9069static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009070#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009072#endif
9073#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009074 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009075#endif
Fred Drakec9680921999-12-13 16:37:25 +00009076#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009078#endif
9079#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009081#endif
9082#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009084#endif
9085#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009087#endif
9088#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009090#endif
9091#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009092 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009093#endif
9094#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009096#endif
9097#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009098 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009099#endif
9100#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009102#endif
9103#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009105#endif
9106#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009108#endif
9109#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009111#endif
9112#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009114#endif
9115#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009117#endif
9118#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009119 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009120#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009121#ifdef _PC_ACL_ENABLED
9122 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9123#endif
9124#ifdef _PC_MIN_HOLE_SIZE
9125 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9126#endif
9127#ifdef _PC_ALLOC_SIZE_MIN
9128 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9129#endif
9130#ifdef _PC_REC_INCR_XFER_SIZE
9131 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9132#endif
9133#ifdef _PC_REC_MAX_XFER_SIZE
9134 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9135#endif
9136#ifdef _PC_REC_MIN_XFER_SIZE
9137 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9138#endif
9139#ifdef _PC_REC_XFER_ALIGN
9140 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9141#endif
9142#ifdef _PC_SYMLINK_MAX
9143 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9144#endif
9145#ifdef _PC_XATTR_ENABLED
9146 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9147#endif
9148#ifdef _PC_XATTR_EXISTS
9149 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9150#endif
9151#ifdef _PC_TIMESTAMP_RESOLUTION
9152 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9153#endif
Fred Drakec9680921999-12-13 16:37:25 +00009154};
9155
Fred Drakec9680921999-12-13 16:37:25 +00009156static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009157conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009158{
9159 return conv_confname(arg, valuep, posix_constants_pathconf,
9160 sizeof(posix_constants_pathconf)
9161 / sizeof(struct constdef));
9162}
9163#endif
9164
9165#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009166PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009167"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009168Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009169If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009170
9171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009172posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009173{
9174 PyObject *result = NULL;
9175 int name, fd;
9176
Fred Drake12c6e2d1999-12-14 21:25:03 +00009177 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9178 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009179 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009180
Stefan Krah0e803b32010-11-26 16:16:47 +00009181 errno = 0;
9182 limit = fpathconf(fd, name);
9183 if (limit == -1 && errno != 0)
9184 posix_error();
9185 else
9186 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009187 }
9188 return result;
9189}
9190#endif
9191
9192
9193#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009194PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009195"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009196Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009197If there is no limit, return -1.\n\
9198On some platforms, path may also be specified as an open file descriptor.\n\
9199 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009200
9201static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009202posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009203{
Georg Brandl306336b2012-06-24 12:55:33 +02009204 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009205 PyObject *result = NULL;
9206 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009207 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009208
Georg Brandl306336b2012-06-24 12:55:33 +02009209 memset(&path, 0, sizeof(path));
9210#ifdef HAVE_FPATHCONF
9211 path.allow_fd = 1;
9212#endif
9213 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9214 path_converter, &path,
9215 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009216 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009217
Victor Stinner8c62be82010-05-06 00:08:46 +00009218 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009219#ifdef HAVE_FPATHCONF
9220 if (path.fd != -1)
9221 limit = fpathconf(path.fd, name);
9222 else
9223#endif
9224 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009225 if (limit == -1 && errno != 0) {
9226 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009227 /* could be a path or name problem */
9228 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009229 else
Georg Brandl306336b2012-06-24 12:55:33 +02009230 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009231 }
9232 else
9233 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009234 }
Georg Brandl306336b2012-06-24 12:55:33 +02009235 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009236 return result;
9237}
9238#endif
9239
9240#ifdef HAVE_CONFSTR
9241static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009242#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009243 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009244#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009245#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009246 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009247#endif
9248#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009249 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009250#endif
Fred Draked86ed291999-12-15 15:34:33 +00009251#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009252 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009253#endif
9254#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009255 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009256#endif
9257#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009258 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009259#endif
9260#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009261 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009262#endif
Fred Drakec9680921999-12-13 16:37:25 +00009263#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009264 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009265#endif
9266#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009267 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009268#endif
9269#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009270 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009271#endif
9272#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009273 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009274#endif
9275#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009276 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009277#endif
9278#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009279 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009280#endif
9281#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009282 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009283#endif
9284#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009286#endif
Fred Draked86ed291999-12-15 15:34:33 +00009287#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009288 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009289#endif
Fred Drakec9680921999-12-13 16:37:25 +00009290#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009291 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009292#endif
Fred Draked86ed291999-12-15 15:34:33 +00009293#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009294 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009295#endif
9296#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009298#endif
9299#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009300 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009301#endif
9302#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009303 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009304#endif
Fred Drakec9680921999-12-13 16:37:25 +00009305#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009306 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009307#endif
9308#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009309 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009310#endif
9311#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009313#endif
9314#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009315 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009316#endif
9317#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009318 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009319#endif
9320#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009321 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009322#endif
9323#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009324 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009325#endif
9326#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009328#endif
9329#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009330 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009331#endif
9332#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009333 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009334#endif
9335#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009336 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009337#endif
9338#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009340#endif
9341#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009342 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009343#endif
9344#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009345 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009346#endif
9347#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009348 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009349#endif
9350#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009352#endif
Fred Draked86ed291999-12-15 15:34:33 +00009353#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009354 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009355#endif
9356#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009358#endif
9359#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009361#endif
9362#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009364#endif
9365#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009366 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009367#endif
9368#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009370#endif
9371#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009373#endif
9374#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009376#endif
9377#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009379#endif
9380#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009382#endif
9383#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009385#endif
9386#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009388#endif
9389#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009391#endif
Fred Drakec9680921999-12-13 16:37:25 +00009392};
9393
9394static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009395conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009396{
9397 return conv_confname(arg, valuep, posix_constants_confstr,
9398 sizeof(posix_constants_confstr)
9399 / sizeof(struct constdef));
9400}
9401
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009402PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009403"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009404Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009405
9406static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009407posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009408{
9409 PyObject *result = NULL;
9410 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009411 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009412 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009413
Victor Stinnercb043522010-09-10 23:49:04 +00009414 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9415 return NULL;
9416
9417 errno = 0;
9418 len = confstr(name, buffer, sizeof(buffer));
9419 if (len == 0) {
9420 if (errno) {
9421 posix_error();
9422 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009423 }
9424 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009425 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009426 }
9427 }
Victor Stinnercb043522010-09-10 23:49:04 +00009428
9429 if ((unsigned int)len >= sizeof(buffer)) {
9430 char *buf = PyMem_Malloc(len);
9431 if (buf == NULL)
9432 return PyErr_NoMemory();
9433 confstr(name, buf, len);
9434 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9435 PyMem_Free(buf);
9436 }
9437 else
9438 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009439 return result;
9440}
9441#endif
9442
9443
9444#ifdef HAVE_SYSCONF
9445static struct constdef posix_constants_sysconf[] = {
9446#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009448#endif
9449#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009451#endif
9452#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009453 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009454#endif
9455#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009457#endif
9458#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009459 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009460#endif
9461#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009463#endif
9464#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009466#endif
9467#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009468 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009469#endif
9470#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009471 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009472#endif
9473#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009474 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009475#endif
Fred Draked86ed291999-12-15 15:34:33 +00009476#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009477 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009478#endif
9479#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009480 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009481#endif
Fred Drakec9680921999-12-13 16:37:25 +00009482#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009483 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009484#endif
Fred Drakec9680921999-12-13 16:37:25 +00009485#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009486 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009487#endif
9488#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009489 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009490#endif
9491#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009492 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009493#endif
9494#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009495 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009496#endif
9497#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009499#endif
Fred Draked86ed291999-12-15 15:34:33 +00009500#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009502#endif
Fred Drakec9680921999-12-13 16:37:25 +00009503#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009505#endif
9506#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009508#endif
9509#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009511#endif
9512#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009514#endif
9515#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009517#endif
Fred Draked86ed291999-12-15 15:34:33 +00009518#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009520#endif
Fred Drakec9680921999-12-13 16:37:25 +00009521#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009523#endif
9524#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009526#endif
9527#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009529#endif
9530#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009532#endif
9533#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009535#endif
9536#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009538#endif
9539#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009541#endif
9542#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009544#endif
9545#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
9548#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009550#endif
9551#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
9554#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
9557#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
9569#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
9572#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009574#endif
9575#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009577#endif
9578#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
9581#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
9584#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
9587#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
Fred Draked86ed291999-12-15 15:34:33 +00009590#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009592#endif
Fred Drakec9680921999-12-13 16:37:25 +00009593#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
Fred Draked86ed291999-12-15 15:34:33 +00009602#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009604#endif
Fred Drakec9680921999-12-13 16:37:25 +00009605#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009607#endif
Fred Draked86ed291999-12-15 15:34:33 +00009608#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009610#endif
9611#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009613#endif
Fred Drakec9680921999-12-13 16:37:25 +00009614#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009616#endif
9617#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009619#endif
9620#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009622#endif
9623#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
Fred Draked86ed291999-12-15 15:34:33 +00009626#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009628#endif
Fred Drakec9680921999-12-13 16:37:25 +00009629#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
9632#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009634#endif
9635#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009637#endif
9638#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009640#endif
9641#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009643#endif
9644#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009646#endif
9647#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009649#endif
Fred Draked86ed291999-12-15 15:34:33 +00009650#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009652#endif
Fred Drakec9680921999-12-13 16:37:25 +00009653#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009655#endif
9656#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009658#endif
Fred Draked86ed291999-12-15 15:34:33 +00009659#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009661#endif
Fred Drakec9680921999-12-13 16:37:25 +00009662#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009664#endif
9665#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009667#endif
9668#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009670#endif
9671#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009673#endif
9674#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009676#endif
9677#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009679#endif
9680#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009682#endif
9683#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009685#endif
9686#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009688#endif
Fred Draked86ed291999-12-15 15:34:33 +00009689#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009691#endif
9692#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009694#endif
Fred Drakec9680921999-12-13 16:37:25 +00009695#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
9698#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
9713#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009715#endif
9716#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009718#endif
9719#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
9722#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009724#endif
9725#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
Fred Draked86ed291999-12-15 15:34:33 +00009800#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009802#endif
Fred Drakec9680921999-12-13 16:37:25 +00009803#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
9890#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938};
9939
9940static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009941conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009942{
9943 return conv_confname(arg, valuep, posix_constants_sysconf,
9944 sizeof(posix_constants_sysconf)
9945 / sizeof(struct constdef));
9946}
9947
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009948PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009949"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009950Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009951
9952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009953posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009954{
9955 PyObject *result = NULL;
9956 int name;
9957
9958 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9959 int value;
9960
9961 errno = 0;
9962 value = sysconf(name);
9963 if (value == -1 && errno != 0)
9964 posix_error();
9965 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009966 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009967 }
9968 return result;
9969}
9970#endif
9971
9972
Fred Drakebec628d1999-12-15 18:31:10 +00009973/* This code is used to ensure that the tables of configuration value names
9974 * are in sorted order as required by conv_confname(), and also to build the
9975 * the exported dictionaries that are used to publish information about the
9976 * names available on the host platform.
9977 *
9978 * Sorting the table at runtime ensures that the table is properly ordered
9979 * when used, even for platforms we're not able to test on. It also makes
9980 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009981 */
Fred Drakebec628d1999-12-15 18:31:10 +00009982
9983static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009984cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009985{
9986 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009988 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009990
9991 return strcmp(c1->name, c2->name);
9992}
9993
9994static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009995setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009997{
Fred Drakebec628d1999-12-15 18:31:10 +00009998 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009999 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010000
10001 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10002 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010003 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010005
Barry Warsaw3155db32000-04-13 15:20:40 +000010006 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 PyObject *o = PyLong_FromLong(table[i].value);
10008 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10009 Py_XDECREF(o);
10010 Py_DECREF(d);
10011 return -1;
10012 }
10013 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010014 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010015 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010016}
10017
Fred Drakebec628d1999-12-15 18:31:10 +000010018/* Return -1 on failure, 0 on success. */
10019static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010020setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010021{
10022#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010023 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010024 sizeof(posix_constants_pathconf)
10025 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010026 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010027 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010028#endif
10029#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010030 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010031 sizeof(posix_constants_confstr)
10032 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010033 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010034 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010035#endif
10036#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010037 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010038 sizeof(posix_constants_sysconf)
10039 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010040 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010041 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010042#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010043 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010044}
Fred Draked86ed291999-12-15 15:34:33 +000010045
10046
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010047PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010048"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010049Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010050in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010051
10052static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010053posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010054{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010055 abort();
10056 /*NOTREACHED*/
10057 Py_FatalError("abort() called from Python code didn't abort!");
10058 return NULL;
10059}
Fred Drakebec628d1999-12-15 18:31:10 +000010060
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010061#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010062PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010063"startfile(filepath [, operation]) - Start a file with its associated\n\
10064application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010065\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010066When \"operation\" is not specified or \"open\", this acts like\n\
10067double-clicking the file in Explorer, or giving the file name as an\n\
10068argument to the DOS \"start\" command: the file is opened with whatever\n\
10069application (if any) its extension is associated.\n\
10070When another \"operation\" is given, it specifies what should be done with\n\
10071the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010072\n\
10073startfile returns as soon as the associated application is launched.\n\
10074There is no option to wait for the application to close, and no way\n\
10075to retrieve the application's exit status.\n\
10076\n\
10077The filepath is relative to the current directory. If you want to use\n\
10078an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010079the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010080
10081static PyObject *
10082win32_startfile(PyObject *self, PyObject *args)
10083{
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 PyObject *ofilepath;
10085 char *filepath;
10086 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010087 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010089
Victor Stinnereb5657a2011-09-30 01:44:27 +020010090 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 if (!PyArg_ParseTuple(args, "U|s:startfile",
10092 &unipath, &operation)) {
10093 PyErr_Clear();
10094 goto normal;
10095 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010096
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010098 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010100 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 PyErr_Clear();
10102 operation = NULL;
10103 goto normal;
10104 }
10105 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010106
Victor Stinnereb5657a2011-09-30 01:44:27 +020010107 wpath = PyUnicode_AsUnicode(unipath);
10108 if (wpath == NULL)
10109 goto normal;
10110 if (uoperation) {
10111 woperation = PyUnicode_AsUnicode(uoperation);
10112 if (woperation == NULL)
10113 goto normal;
10114 }
10115 else
10116 woperation = NULL;
10117
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010119 rc = ShellExecuteW((HWND)0, woperation, wpath,
10120 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 Py_END_ALLOW_THREADS
10122
Victor Stinnereb5657a2011-09-30 01:44:27 +020010123 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010125 win32_error_object("startfile", unipath);
10126 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 }
10128 Py_INCREF(Py_None);
10129 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010130
10131normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10133 PyUnicode_FSConverter, &ofilepath,
10134 &operation))
10135 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010136 if (win32_warn_bytes_api()) {
10137 Py_DECREF(ofilepath);
10138 return NULL;
10139 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 filepath = PyBytes_AsString(ofilepath);
10141 Py_BEGIN_ALLOW_THREADS
10142 rc = ShellExecute((HWND)0, operation, filepath,
10143 NULL, NULL, SW_SHOWNORMAL);
10144 Py_END_ALLOW_THREADS
10145 if (rc <= (HINSTANCE)32) {
10146 PyObject *errval = win32_error("startfile", filepath);
10147 Py_DECREF(ofilepath);
10148 return errval;
10149 }
10150 Py_DECREF(ofilepath);
10151 Py_INCREF(Py_None);
10152 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010153}
10154#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010155
Martin v. Löwis438b5342002-12-27 10:16:42 +000010156#ifdef HAVE_GETLOADAVG
10157PyDoc_STRVAR(posix_getloadavg__doc__,
10158"getloadavg() -> (float, float, float)\n\n\
10159Return the number of processes in the system run queue averaged over\n\
10160the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10161was unobtainable");
10162
10163static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010164posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010165{
10166 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010167 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010168 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10169 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010170 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010171 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010172}
10173#endif
10174
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010175PyDoc_STRVAR(device_encoding__doc__,
10176"device_encoding(fd) -> str\n\n\
10177Return a string describing the encoding of the device\n\
10178if the output is a terminal; else return None.");
10179
10180static PyObject *
10181device_encoding(PyObject *self, PyObject *args)
10182{
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010184
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10186 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010187
10188 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010189}
10190
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010191#ifdef HAVE_SETRESUID
10192PyDoc_STRVAR(posix_setresuid__doc__,
10193"setresuid(ruid, euid, suid)\n\n\
10194Set the current process's real, effective, and saved user ids.");
10195
10196static PyObject*
10197posix_setresuid (PyObject *self, PyObject *args)
10198{
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 /* We assume uid_t is no larger than a long. */
10200 long ruid, euid, suid;
10201 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
10202 return NULL;
10203 if (setresuid(ruid, euid, suid) < 0)
10204 return posix_error();
10205 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010206}
10207#endif
10208
10209#ifdef HAVE_SETRESGID
10210PyDoc_STRVAR(posix_setresgid__doc__,
10211"setresgid(rgid, egid, sgid)\n\n\
10212Set the current process's real, effective, and saved group ids.");
10213
10214static PyObject*
10215posix_setresgid (PyObject *self, PyObject *args)
10216{
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 /* We assume uid_t is no larger than a long. */
10218 long rgid, egid, sgid;
10219 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
10220 return NULL;
10221 if (setresgid(rgid, egid, sgid) < 0)
10222 return posix_error();
10223 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010224}
10225#endif
10226
10227#ifdef HAVE_GETRESUID
10228PyDoc_STRVAR(posix_getresuid__doc__,
10229"getresuid() -> (ruid, euid, suid)\n\n\
10230Get tuple of the current process's real, effective, and saved user ids.");
10231
10232static PyObject*
10233posix_getresuid (PyObject *self, PyObject *noargs)
10234{
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 uid_t ruid, euid, suid;
10236 long l_ruid, l_euid, l_suid;
10237 if (getresuid(&ruid, &euid, &suid) < 0)
10238 return posix_error();
10239 /* Force the values into long's as we don't know the size of uid_t. */
10240 l_ruid = ruid;
10241 l_euid = euid;
10242 l_suid = suid;
10243 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010244}
10245#endif
10246
10247#ifdef HAVE_GETRESGID
10248PyDoc_STRVAR(posix_getresgid__doc__,
10249"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010250Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010251
10252static PyObject*
10253posix_getresgid (PyObject *self, PyObject *noargs)
10254{
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 uid_t rgid, egid, sgid;
10256 long l_rgid, l_egid, l_sgid;
10257 if (getresgid(&rgid, &egid, &sgid) < 0)
10258 return posix_error();
10259 /* Force the values into long's as we don't know the size of uid_t. */
10260 l_rgid = rgid;
10261 l_egid = egid;
10262 l_sgid = sgid;
10263 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010264}
10265#endif
10266
Benjamin Peterson9428d532011-09-14 11:45:52 -040010267#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010268
Benjamin Peterson799bd802011-08-31 22:15:17 -040010269PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010270"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10271Return the value of extended attribute attribute on path.\n\
10272\n\
10273path may be either a string or an open file descriptor.\n\
10274If follow_symlinks is False, and the last element of the path is a symbolic\n\
10275 link, getxattr will examine the symbolic link itself instead of the file\n\
10276 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010277
10278static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010279posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010280{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010281 path_t path;
10282 path_t attribute;
10283 int follow_symlinks = 1;
10284 PyObject *buffer = NULL;
10285 int i;
10286 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010287
Larry Hastings9cf065c2012-06-22 16:30:09 -070010288 memset(&path, 0, sizeof(path));
10289 memset(&attribute, 0, sizeof(attribute));
10290 path.allow_fd = 1;
10291 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10292 path_converter, &path,
10293 path_converter, &attribute,
10294 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010295 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010296
Larry Hastings9cf065c2012-06-22 16:30:09 -070010297 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10298 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010299
Larry Hastings9cf065c2012-06-22 16:30:09 -070010300 for (i = 0; ; i++) {
10301 void *ptr;
10302 ssize_t result;
10303 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10304 Py_ssize_t buffer_size = buffer_sizes[i];
10305 if (!buffer_size) {
10306 path_error("getxattr", &path);
10307 goto exit;
10308 }
10309 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10310 if (!buffer)
10311 goto exit;
10312 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010313
Larry Hastings9cf065c2012-06-22 16:30:09 -070010314 Py_BEGIN_ALLOW_THREADS;
10315 if (path.fd >= 0)
10316 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10317 else if (follow_symlinks)
10318 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10319 else
10320 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10321 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010322
Larry Hastings9cf065c2012-06-22 16:30:09 -070010323 if (result < 0) {
10324 Py_DECREF(buffer);
10325 buffer = NULL;
10326 if (errno == ERANGE)
10327 continue;
10328 path_error("getxattr", &path);
10329 goto exit;
10330 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010331
Larry Hastings9cf065c2012-06-22 16:30:09 -070010332 if (result != buffer_size) {
10333 /* Can only shrink. */
10334 _PyBytes_Resize(&buffer, result);
10335 }
10336 break;
10337 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010338
Larry Hastings9cf065c2012-06-22 16:30:09 -070010339exit:
10340 path_cleanup(&path);
10341 path_cleanup(&attribute);
10342 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010343}
10344
10345PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010346"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10347Set extended attribute attribute on path to value.\n\
10348path may be either a string or an open file descriptor.\n\
10349If follow_symlinks is False, and the last element of the path is a symbolic\n\
10350 link, setxattr will modify the symbolic link itself instead of the file\n\
10351 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010352
10353static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010354posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010355{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010356 path_t path;
10357 path_t attribute;
10358 Py_buffer value;
10359 int flags = 0;
10360 int follow_symlinks = 1;
10361 int result;
10362 PyObject *return_value = NULL;
10363 static char *keywords[] = {"path", "attribute", "value",
10364 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010365
Larry Hastings9cf065c2012-06-22 16:30:09 -070010366 memset(&path, 0, sizeof(path));
10367 path.allow_fd = 1;
10368 memset(&attribute, 0, sizeof(attribute));
10369 memset(&value, 0, sizeof(value));
10370 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10371 keywords,
10372 path_converter, &path,
10373 path_converter, &attribute,
10374 &value, &flags,
10375 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010376 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010377
10378 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10379 goto exit;
10380
Benjamin Peterson799bd802011-08-31 22:15:17 -040010381 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010382 if (path.fd > -1)
10383 result = fsetxattr(path.fd, attribute.narrow,
10384 value.buf, value.len, flags);
10385 else if (follow_symlinks)
10386 result = setxattr(path.narrow, attribute.narrow,
10387 value.buf, value.len, flags);
10388 else
10389 result = lsetxattr(path.narrow, attribute.narrow,
10390 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010391 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010392
Larry Hastings9cf065c2012-06-22 16:30:09 -070010393 if (result) {
10394 return_value = path_error("setxattr", &path);
10395 goto exit;
10396 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010397
Larry Hastings9cf065c2012-06-22 16:30:09 -070010398 return_value = Py_None;
10399 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010400
Larry Hastings9cf065c2012-06-22 16:30:09 -070010401exit:
10402 path_cleanup(&path);
10403 path_cleanup(&attribute);
10404 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010405
Larry Hastings9cf065c2012-06-22 16:30:09 -070010406 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010407}
10408
10409PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010410"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10411Remove extended attribute attribute on path.\n\
10412path may be either a string or an open file descriptor.\n\
10413If follow_symlinks is False, and the last element of the path is a symbolic\n\
10414 link, removexattr will modify the symbolic link itself instead of the file\n\
10415 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010416
10417static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010418posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010419{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010420 path_t path;
10421 path_t attribute;
10422 int follow_symlinks = 1;
10423 int result;
10424 PyObject *return_value = NULL;
10425 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010426
Larry Hastings9cf065c2012-06-22 16:30:09 -070010427 memset(&path, 0, sizeof(path));
10428 memset(&attribute, 0, sizeof(attribute));
10429 path.allow_fd = 1;
10430 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10431 keywords,
10432 path_converter, &path,
10433 path_converter, &attribute,
10434 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010435 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010436
10437 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10438 goto exit;
10439
Benjamin Peterson799bd802011-08-31 22:15:17 -040010440 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010441 if (path.fd > -1)
10442 result = fremovexattr(path.fd, attribute.narrow);
10443 else if (follow_symlinks)
10444 result = removexattr(path.narrow, attribute.narrow);
10445 else
10446 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010447 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010448
Larry Hastings9cf065c2012-06-22 16:30:09 -070010449 if (result) {
10450 return_value = path_error("removexattr", &path);
10451 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010452 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010453
Larry Hastings9cf065c2012-06-22 16:30:09 -070010454 return_value = Py_None;
10455 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010456
Larry Hastings9cf065c2012-06-22 16:30:09 -070010457exit:
10458 path_cleanup(&path);
10459 path_cleanup(&attribute);
10460
10461 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010462}
10463
10464PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010465"listxattr(path='.', *, follow_symlinks=True)\n\n\
10466Return a list of extended attributes on path.\n\
10467\n\
10468path may be either None, a string, or an open file descriptor.\n\
10469if path is None, listxattr will examine the current directory.\n\
10470If follow_symlinks is False, and the last element of the path is a symbolic\n\
10471 link, listxattr will examine the symbolic link itself instead of the file\n\
10472 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010473
10474static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010475posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010476{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010477 path_t path;
10478 int follow_symlinks = 1;
10479 Py_ssize_t i;
10480 PyObject *result = NULL;
10481 char *buffer = NULL;
10482 char *name;
10483 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010484
Larry Hastings9cf065c2012-06-22 16:30:09 -070010485 memset(&path, 0, sizeof(path));
10486 path.allow_fd = 1;
10487 path.fd = -1;
10488 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10489 path_converter, &path,
10490 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010491 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010492
Larry Hastings9cf065c2012-06-22 16:30:09 -070010493 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10494 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010495
Larry Hastings9cf065c2012-06-22 16:30:09 -070010496 name = path.narrow ? path.narrow : ".";
10497 for (i = 0; ; i++) {
10498 char *start, *trace, *end;
10499 ssize_t length;
10500 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10501 Py_ssize_t buffer_size = buffer_sizes[i];
10502 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010503 /* ERANGE */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010504 path_error("listxattr", &path);
10505 break;
10506 }
10507 buffer = PyMem_MALLOC(buffer_size);
10508 if (!buffer) {
10509 PyErr_NoMemory();
10510 break;
10511 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010512
Larry Hastings9cf065c2012-06-22 16:30:09 -070010513 Py_BEGIN_ALLOW_THREADS;
10514 if (path.fd > -1)
10515 length = flistxattr(path.fd, buffer, buffer_size);
10516 else if (follow_symlinks)
10517 length = listxattr(name, buffer, buffer_size);
10518 else
10519 length = llistxattr(name, buffer, buffer_size);
10520 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010521
Larry Hastings9cf065c2012-06-22 16:30:09 -070010522 if (length < 0) {
10523 if (errno == ERANGE)
10524 continue;
10525 path_error("listxattr", &path);
10526 break;
10527 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010528
Larry Hastings9cf065c2012-06-22 16:30:09 -070010529 result = PyList_New(0);
10530 if (!result) {
10531 goto exit;
10532 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010533
Larry Hastings9cf065c2012-06-22 16:30:09 -070010534 end = buffer + length;
10535 for (trace = start = buffer; trace != end; trace++) {
10536 if (!*trace) {
10537 int error;
10538 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10539 trace - start);
10540 if (!attribute) {
10541 Py_DECREF(result);
10542 result = NULL;
10543 goto exit;
10544 }
10545 error = PyList_Append(result, attribute);
10546 Py_DECREF(attribute);
10547 if (error) {
10548 Py_DECREF(result);
10549 result = NULL;
10550 goto exit;
10551 }
10552 start = trace + 1;
10553 }
10554 }
10555 break;
10556 }
10557exit:
10558 path_cleanup(&path);
10559 if (buffer)
10560 PyMem_FREE(buffer);
10561 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010562}
10563
Benjamin Peterson9428d532011-09-14 11:45:52 -040010564#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010565
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010566
Georg Brandl2fb477c2012-02-21 00:33:36 +010010567PyDoc_STRVAR(posix_urandom__doc__,
10568"urandom(n) -> str\n\n\
10569Return n random bytes suitable for cryptographic use.");
10570
10571static PyObject *
10572posix_urandom(PyObject *self, PyObject *args)
10573{
10574 Py_ssize_t size;
10575 PyObject *result;
10576 int ret;
10577
10578 /* Read arguments */
10579 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10580 return NULL;
10581 if (size < 0)
10582 return PyErr_Format(PyExc_ValueError,
10583 "negative argument not allowed");
10584 result = PyBytes_FromStringAndSize(NULL, size);
10585 if (result == NULL)
10586 return NULL;
10587
10588 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10589 PyBytes_GET_SIZE(result));
10590 if (ret == -1) {
10591 Py_DECREF(result);
10592 return NULL;
10593 }
10594 return result;
10595}
10596
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010597/* Terminal size querying */
10598
10599static PyTypeObject TerminalSizeType;
10600
10601PyDoc_STRVAR(TerminalSize_docstring,
10602 "A tuple of (columns, lines) for holding terminal window size");
10603
10604static PyStructSequence_Field TerminalSize_fields[] = {
10605 {"columns", "width of the terminal window in characters"},
10606 {"lines", "height of the terminal window in characters"},
10607 {NULL, NULL}
10608};
10609
10610static PyStructSequence_Desc TerminalSize_desc = {
10611 "os.terminal_size",
10612 TerminalSize_docstring,
10613 TerminalSize_fields,
10614 2,
10615};
10616
10617#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10618PyDoc_STRVAR(termsize__doc__,
10619 "Return the size of the terminal window as (columns, lines).\n" \
10620 "\n" \
10621 "The optional argument fd (default standard output) specifies\n" \
10622 "which file descriptor should be queried.\n" \
10623 "\n" \
10624 "If the file descriptor is not connected to a terminal, an OSError\n" \
10625 "is thrown.\n" \
10626 "\n" \
10627 "This function will only be defined if an implementation is\n" \
10628 "available for this system.\n" \
10629 "\n" \
10630 "shutil.get_terminal_size is the high-level function which should \n" \
10631 "normally be used, os.get_terminal_size is the low-level implementation.");
10632
10633static PyObject*
10634get_terminal_size(PyObject *self, PyObject *args)
10635{
10636 int columns, lines;
10637 PyObject *termsize;
10638
10639 int fd = fileno(stdout);
10640 /* Under some conditions stdout may not be connected and
10641 * fileno(stdout) may point to an invalid file descriptor. For example
10642 * GUI apps don't have valid standard streams by default.
10643 *
10644 * If this happens, and the optional fd argument is not present,
10645 * the ioctl below will fail returning EBADF. This is what we want.
10646 */
10647
10648 if (!PyArg_ParseTuple(args, "|i", &fd))
10649 return NULL;
10650
10651#ifdef TERMSIZE_USE_IOCTL
10652 {
10653 struct winsize w;
10654 if (ioctl(fd, TIOCGWINSZ, &w))
10655 return PyErr_SetFromErrno(PyExc_OSError);
10656 columns = w.ws_col;
10657 lines = w.ws_row;
10658 }
10659#endif /* TERMSIZE_USE_IOCTL */
10660
10661#ifdef TERMSIZE_USE_CONIO
10662 {
10663 DWORD nhandle;
10664 HANDLE handle;
10665 CONSOLE_SCREEN_BUFFER_INFO csbi;
10666 switch (fd) {
10667 case 0: nhandle = STD_INPUT_HANDLE;
10668 break;
10669 case 1: nhandle = STD_OUTPUT_HANDLE;
10670 break;
10671 case 2: nhandle = STD_ERROR_HANDLE;
10672 break;
10673 default:
10674 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10675 }
10676 handle = GetStdHandle(nhandle);
10677 if (handle == NULL)
10678 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10679 if (handle == INVALID_HANDLE_VALUE)
10680 return PyErr_SetFromWindowsErr(0);
10681
10682 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10683 return PyErr_SetFromWindowsErr(0);
10684
10685 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10686 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10687 }
10688#endif /* TERMSIZE_USE_CONIO */
10689
10690 termsize = PyStructSequence_New(&TerminalSizeType);
10691 if (termsize == NULL)
10692 return NULL;
10693 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10694 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10695 if (PyErr_Occurred()) {
10696 Py_DECREF(termsize);
10697 return NULL;
10698 }
10699 return termsize;
10700}
10701#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10702
10703
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010704static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010705 {"access", (PyCFunction)posix_access,
10706 METH_VARARGS | METH_KEYWORDS,
10707 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010708#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010710#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010711 {"chdir", (PyCFunction)posix_chdir,
10712 METH_VARARGS | METH_KEYWORDS,
10713 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010714#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010715 {"chflags", (PyCFunction)posix_chflags,
10716 METH_VARARGS | METH_KEYWORDS,
10717 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010718#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010719 {"chmod", (PyCFunction)posix_chmod,
10720 METH_VARARGS | METH_KEYWORDS,
10721 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010722#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010724#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010725#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010726 {"chown", (PyCFunction)posix_chown,
10727 METH_VARARGS | METH_KEYWORDS,
10728 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010729#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010730#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010731 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010732#endif /* HAVE_LCHMOD */
10733#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010734 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010735#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010736#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010737 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010738#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010739#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010740 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010741#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010742#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010743 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010744#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010745#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010747#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010748#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10750 METH_NOARGS, posix_getcwd__doc__},
10751 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10752 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010753#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010754#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10755 {"link", (PyCFunction)posix_link,
10756 METH_VARARGS | METH_KEYWORDS,
10757 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010758#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010759 {"listdir", (PyCFunction)posix_listdir,
10760 METH_VARARGS | METH_KEYWORDS,
10761 posix_listdir__doc__},
10762 {"lstat", (PyCFunction)posix_lstat,
10763 METH_VARARGS | METH_KEYWORDS,
10764 posix_lstat__doc__},
10765 {"mkdir", (PyCFunction)posix_mkdir,
10766 METH_VARARGS | METH_KEYWORDS,
10767 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010768#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010770#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010771#ifdef HAVE_GETPRIORITY
10772 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10773#endif /* HAVE_GETPRIORITY */
10774#ifdef HAVE_SETPRIORITY
10775 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10776#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010777#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010778 {"readlink", (PyCFunction)posix_readlink,
10779 METH_VARARGS | METH_KEYWORDS,
10780 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010781#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010782#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010783 {"readlink", (PyCFunction)win_readlink,
10784 METH_VARARGS | METH_KEYWORDS,
10785 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010786#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010787 {"rename", (PyCFunction)posix_rename,
10788 METH_VARARGS | METH_KEYWORDS,
10789 posix_rename__doc__},
10790 {"replace", (PyCFunction)posix_replace,
10791 METH_VARARGS | METH_KEYWORDS,
10792 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010793 {"rmdir", (PyCFunction)posix_rmdir,
10794 METH_VARARGS | METH_KEYWORDS,
10795 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010796 {"stat", (PyCFunction)posix_stat,
10797 METH_VARARGS | METH_KEYWORDS,
10798 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010800#if defined(HAVE_SYMLINK)
10801 {"symlink", (PyCFunction)posix_symlink,
10802 METH_VARARGS | METH_KEYWORDS,
10803 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010804#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010805#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010806 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010807#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010809#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010810 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010811#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010812 {"unlink", (PyCFunction)posix_unlink,
10813 METH_VARARGS | METH_KEYWORDS,
10814 posix_unlink__doc__},
10815 {"remove", (PyCFunction)posix_unlink,
10816 METH_VARARGS | METH_KEYWORDS,
10817 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010818 {"utime", (PyCFunction)posix_utime,
10819 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010820#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010822#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010824#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010825 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010826 {"execve", (PyCFunction)posix_execve,
10827 METH_VARARGS | METH_KEYWORDS,
10828 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010829#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010830#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010831 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10832 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010833#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10835 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010836#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010837#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010838#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010840#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010841#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010842 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010843#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010844#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010845#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010846 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10847 {"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 +020010848#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010849#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010850 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010851#endif
10852#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010853 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010854#endif
10855#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010856 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010857#endif
10858#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010859 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010860#endif
10861#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010862 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010863#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010864 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010865#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010866 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10867 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10868#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010869#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010870#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010872#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010873#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010874 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010875#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010876#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010877 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010878#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010879#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010880 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010881#endif /* HAVE_GETEUID */
10882#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010884#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010885#ifdef HAVE_GETGROUPLIST
10886 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10887#endif
Fred Drakec9680921999-12-13 16:37:25 +000010888#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010890#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010892#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010894#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010895#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010897#endif /* HAVE_GETPPID */
10898#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010899 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010900#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010901#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010903#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010904#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010906#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010907#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010908 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010909#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010910#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010911 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010912#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010913#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010914 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10915 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010916#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010917#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010919#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010920#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010922#endif /* HAVE_SETEUID */
10923#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010925#endif /* HAVE_SETEGID */
10926#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010928#endif /* HAVE_SETREUID */
10929#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010931#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010932#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010934#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010935#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010937#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010938#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010940#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010941#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010943#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010944#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010946#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010947#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010949#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010950#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010951 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010952#endif /* HAVE_WAIT3 */
10953#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010954 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010955#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010956#if defined(HAVE_WAITID) && !defined(__APPLE__)
10957 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10958#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010959#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010960 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010961#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010962#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010964#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010965#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010967#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010968#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010970#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010971#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010972 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010973#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010974#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010975 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010976#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010977 {"open", (PyCFunction)posix_open,\
10978 METH_VARARGS | METH_KEYWORDS,
10979 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10981 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10982 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10983 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10984 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010985#ifdef HAVE_LOCKF
10986 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10987#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010988 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10989 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010990#ifdef HAVE_READV
10991 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10992#endif
10993#ifdef HAVE_PREAD
10994 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10995#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010996 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010997#ifdef HAVE_WRITEV
10998 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10999#endif
11000#ifdef HAVE_PWRITE
11001 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11002#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011003#ifdef HAVE_SENDFILE
11004 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11005 posix_sendfile__doc__},
11006#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011007 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011009#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011011#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011012#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011013 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011014#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011015#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011016 {"mkfifo", (PyCFunction)posix_mkfifo,
11017 METH_VARARGS | METH_KEYWORDS,
11018 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011019#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011020#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011021 {"mknod", (PyCFunction)posix_mknod,
11022 METH_VARARGS | METH_KEYWORDS,
11023 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011024#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011025#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11027 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11028 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011029#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011030#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011031 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011032#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011033#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011034 {"truncate", (PyCFunction)posix_truncate,
11035 METH_VARARGS | METH_KEYWORDS,
11036 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011037#endif
11038#ifdef HAVE_POSIX_FALLOCATE
11039 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11040#endif
11041#ifdef HAVE_POSIX_FADVISE
11042 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11043#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011044#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011045 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011046#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011047#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011048 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011049#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011051#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011053#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011054#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011056#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011057#ifdef HAVE_SYNC
11058 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11059#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011060#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011062#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011063#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011064#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011066#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011067#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011069#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011070#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011072#endif /* WIFSTOPPED */
11073#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011075#endif /* WIFSIGNALED */
11076#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011078#endif /* WIFEXITED */
11079#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011081#endif /* WEXITSTATUS */
11082#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011084#endif /* WTERMSIG */
11085#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011087#endif /* WSTOPSIG */
11088#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011089#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011090 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011091#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011092#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011093 {"statvfs", (PyCFunction)posix_statvfs,
11094 METH_VARARGS | METH_KEYWORDS,
11095 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011096#endif
Fred Drakec9680921999-12-13 16:37:25 +000011097#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011099#endif
11100#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011102#endif
11103#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011105#endif
11106#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011107 {"pathconf", (PyCFunction)posix_pathconf,
11108 METH_VARARGS | METH_KEYWORDS,
11109 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011110#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011111 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011112#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011114 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011115 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011116 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011117 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011118#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011119#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011120 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011121#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011122 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011123#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011125#endif
11126#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011128#endif
11129#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011131#endif
11132#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011133 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011134#endif
11135
Benjamin Peterson9428d532011-09-14 11:45:52 -040011136#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011137 {"setxattr", (PyCFunction)posix_setxattr,
11138 METH_VARARGS | METH_KEYWORDS,
11139 posix_setxattr__doc__},
11140 {"getxattr", (PyCFunction)posix_getxattr,
11141 METH_VARARGS | METH_KEYWORDS,
11142 posix_getxattr__doc__},
11143 {"removexattr", (PyCFunction)posix_removexattr,
11144 METH_VARARGS | METH_KEYWORDS,
11145 posix_removexattr__doc__},
11146 {"listxattr", (PyCFunction)posix_listxattr,
11147 METH_VARARGS | METH_KEYWORDS,
11148 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011149#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011150#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11151 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11152#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011153 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011154};
11155
11156
Barry Warsaw4a342091996-12-19 23:50:02 +000011157static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011158ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011159{
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011161}
11162
Guido van Rossumd48f2521997-12-05 22:19:34 +000011163#if defined(PYOS_OS2)
11164/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011165static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011166{
11167 APIRET rc;
11168 ULONG values[QSV_MAX+1];
11169 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011170 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011171
11172 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011173 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011174 Py_END_ALLOW_THREADS
11175
11176 if (rc != NO_ERROR) {
11177 os2_error(rc);
11178 return -1;
11179 }
11180
Fred Drake4d1e64b2002-04-15 19:40:07 +000011181 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11182 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11183 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11184 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11185 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11186 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11187 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011188
11189 switch (values[QSV_VERSION_MINOR]) {
11190 case 0: ver = "2.00"; break;
11191 case 10: ver = "2.10"; break;
11192 case 11: ver = "2.11"; break;
11193 case 30: ver = "3.00"; break;
11194 case 40: ver = "4.00"; break;
11195 case 50: ver = "5.00"; break;
11196 default:
Tim Peters885d4572001-11-28 20:27:42 +000011197 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011198 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011199 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011200 ver = &tmp[0];
11201 }
11202
11203 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011204 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011205 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011206
11207 /* Add Indicator of Which Drive was Used to Boot the System */
11208 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11209 tmp[1] = ':';
11210 tmp[2] = '\0';
11211
Fred Drake4d1e64b2002-04-15 19:40:07 +000011212 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011213}
11214#endif
11215
Brian Curtin52173d42010-12-02 18:29:18 +000011216#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011217static int
Brian Curtin52173d42010-12-02 18:29:18 +000011218enable_symlink()
11219{
11220 HANDLE tok;
11221 TOKEN_PRIVILEGES tok_priv;
11222 LUID luid;
11223 int meth_idx = 0;
11224
11225 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011226 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011227
11228 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011229 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011230
11231 tok_priv.PrivilegeCount = 1;
11232 tok_priv.Privileges[0].Luid = luid;
11233 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11234
11235 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11236 sizeof(TOKEN_PRIVILEGES),
11237 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011238 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011239
Brian Curtin3b4499c2010-12-28 14:31:47 +000011240 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11241 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011242}
11243#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11244
Barry Warsaw4a342091996-12-19 23:50:02 +000011245static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011246all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011247{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011248#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011249 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011250#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011251#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011252 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011253#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011254#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011255 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011256#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011257#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011259#endif
Fred Drakec9680921999-12-13 16:37:25 +000011260#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011261 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011262#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011263#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011264 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011265#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011266#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011267 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011268#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011269#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011270 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011271#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011272#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011273 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011274#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011275#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011276 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011277#endif
11278#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011279 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011280#endif
11281#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011282 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011283#endif
11284#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011286#endif
11287#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011288 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011289#endif
11290#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011291 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011292#endif
11293#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011295#endif
11296#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011298#endif
11299#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011300 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011301#endif
11302#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011304#endif
11305#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011307#endif
11308#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011310#endif
11311#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011313#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011314#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011315 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011316#endif
11317#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011318 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011319#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011320#ifdef O_XATTR
11321 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11322#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011323#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011324 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011325#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011326#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011327 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011328#endif
11329#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011331#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011332#ifdef O_EXEC
11333 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11334#endif
11335#ifdef O_SEARCH
11336 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11337#endif
11338#ifdef O_TTY_INIT
11339 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11340#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011341#ifdef PRIO_PROCESS
11342 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11343#endif
11344#ifdef PRIO_PGRP
11345 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11346#endif
11347#ifdef PRIO_USER
11348 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11349#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011350#ifdef O_CLOEXEC
11351 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11352#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011353#ifdef O_ACCMODE
11354 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11355#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011356
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011357
Jesus Cea94363612012-06-22 18:32:07 +020011358#ifdef SEEK_HOLE
11359 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11360#endif
11361#ifdef SEEK_DATA
11362 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11363#endif
11364
Tim Peters5aa91602002-01-30 05:46:57 +000011365/* MS Windows */
11366#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 /* Don't inherit in child processes. */
11368 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011369#endif
11370#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 /* Optimize for short life (keep in memory). */
11372 /* MS forgot to define this one with a non-underscore form too. */
11373 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011374#endif
11375#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 /* Automatically delete when last handle is closed. */
11377 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011378#endif
11379#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011380 /* Optimize for random access. */
11381 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011382#endif
11383#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 /* Optimize for sequential access. */
11385 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011386#endif
11387
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011388/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011389#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 /* Send a SIGIO signal whenever input or output
11391 becomes available on file descriptor */
11392 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011393#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011394#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011395 /* Direct disk access. */
11396 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011397#endif
11398#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011399 /* Must be a directory. */
11400 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011401#endif
11402#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 /* Do not follow links. */
11404 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011405#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011406#ifdef O_NOLINKS
11407 /* Fails if link count of the named file is greater than 1 */
11408 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11409#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011410#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 /* Do not update the access time. */
11412 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011413#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011414
Victor Stinner8c62be82010-05-06 00:08:46 +000011415 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011416#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011418#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011419#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011420 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011421#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011422#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011424#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011425#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011427#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011428#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011430#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011431#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011433#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011434#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011435 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011436#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011437#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011439#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011440#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011442#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011443#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011445#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011446#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011447 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011448#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011449#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011450 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011451#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011452#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011453 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011454#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011455#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011456 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011457#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011458#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011459 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011460#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011461#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011462 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011463#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011464#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011466#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011467
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011468 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011469#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011470 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011471#endif /* ST_RDONLY */
11472#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011473 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011474#endif /* ST_NOSUID */
11475
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011476 /* FreeBSD sendfile() constants */
11477#ifdef SF_NODISKIO
11478 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11479#endif
11480#ifdef SF_MNOWAIT
11481 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11482#endif
11483#ifdef SF_SYNC
11484 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11485#endif
11486
Ross Lagerwall7807c352011-03-17 20:20:30 +020011487 /* constants for posix_fadvise */
11488#ifdef POSIX_FADV_NORMAL
11489 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11490#endif
11491#ifdef POSIX_FADV_SEQUENTIAL
11492 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11493#endif
11494#ifdef POSIX_FADV_RANDOM
11495 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11496#endif
11497#ifdef POSIX_FADV_NOREUSE
11498 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11499#endif
11500#ifdef POSIX_FADV_WILLNEED
11501 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11502#endif
11503#ifdef POSIX_FADV_DONTNEED
11504 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11505#endif
11506
11507 /* constants for waitid */
11508#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11509 if (ins(d, "P_PID", (long)P_PID)) return -1;
11510 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11511 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11512#endif
11513#ifdef WEXITED
11514 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11515#endif
11516#ifdef WNOWAIT
11517 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11518#endif
11519#ifdef WSTOPPED
11520 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11521#endif
11522#ifdef CLD_EXITED
11523 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11524#endif
11525#ifdef CLD_DUMPED
11526 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11527#endif
11528#ifdef CLD_TRAPPED
11529 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11530#endif
11531#ifdef CLD_CONTINUED
11532 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11533#endif
11534
11535 /* constants for lockf */
11536#ifdef F_LOCK
11537 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11538#endif
11539#ifdef F_TLOCK
11540 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11541#endif
11542#ifdef F_ULOCK
11543 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11544#endif
11545#ifdef F_TEST
11546 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11547#endif
11548
Guido van Rossum246bc171999-02-01 23:54:31 +000011549#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011550#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11552 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11553 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11554 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11555 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11556 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11557 if (ins(d, "P_PM", (long)P_PM)) return -1;
11558 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11559 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11560 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11561 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11562 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11563 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11564 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11565 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11566 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11567 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11568 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11569 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11570 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011571#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011572 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11573 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11574 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11575 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11576 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011577#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011578#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011579
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011580#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011581 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011582 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11583 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11584#ifdef SCHED_SPORADIC
11585 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11586#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011587#ifdef SCHED_BATCH
11588 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11589#endif
11590#ifdef SCHED_IDLE
11591 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11592#endif
11593#ifdef SCHED_RESET_ON_FORK
11594 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11595#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011596#ifdef SCHED_SYS
11597 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11598#endif
11599#ifdef SCHED_IA
11600 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11601#endif
11602#ifdef SCHED_FSS
11603 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11604#endif
11605#ifdef SCHED_FX
11606 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11607#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011608#endif
11609
Benjamin Peterson9428d532011-09-14 11:45:52 -040011610#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011611 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11612 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11613 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11614#endif
11615
Victor Stinner8b905bd2011-10-25 13:34:04 +020011616#ifdef RTLD_LAZY
11617 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11618#endif
11619#ifdef RTLD_NOW
11620 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11621#endif
11622#ifdef RTLD_GLOBAL
11623 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11624#endif
11625#ifdef RTLD_LOCAL
11626 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11627#endif
11628#ifdef RTLD_NODELETE
11629 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11630#endif
11631#ifdef RTLD_NOLOAD
11632 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11633#endif
11634#ifdef RTLD_DEEPBIND
11635 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11636#endif
11637
Guido van Rossumd48f2521997-12-05 22:19:34 +000011638#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011639 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011640#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011641 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011642}
11643
11644
Tim Peters5aa91602002-01-30 05:46:57 +000011645#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011646#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011647#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011648
11649#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011650#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011651#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011652
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011653#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011654#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011655#define MODNAME "posix"
11656#endif
11657
Martin v. Löwis1a214512008-06-11 05:26:20 +000011658static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011659 PyModuleDef_HEAD_INIT,
11660 MODNAME,
11661 posix__doc__,
11662 -1,
11663 posix_methods,
11664 NULL,
11665 NULL,
11666 NULL,
11667 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011668};
11669
11670
Larry Hastings9cf065c2012-06-22 16:30:09 -070011671static char *have_functions[] = {
11672
11673#ifdef HAVE_FACCESSAT
11674 "HAVE_FACCESSAT",
11675#endif
11676
11677#ifdef HAVE_FCHDIR
11678 "HAVE_FCHDIR",
11679#endif
11680
11681#ifdef HAVE_FCHMOD
11682 "HAVE_FCHMOD",
11683#endif
11684
11685#ifdef HAVE_FCHMODAT
11686 "HAVE_FCHMODAT",
11687#endif
11688
11689#ifdef HAVE_FCHOWN
11690 "HAVE_FCHOWN",
11691#endif
11692
11693#ifdef HAVE_FEXECVE
11694 "HAVE_FEXECVE",
11695#endif
11696
11697#ifdef HAVE_FDOPENDIR
11698 "HAVE_FDOPENDIR",
11699#endif
11700
Georg Brandl306336b2012-06-24 12:55:33 +020011701#ifdef HAVE_FPATHCONF
11702 "HAVE_FPATHCONF",
11703#endif
11704
Larry Hastings9cf065c2012-06-22 16:30:09 -070011705#ifdef HAVE_FSTATAT
11706 "HAVE_FSTATAT",
11707#endif
11708
11709#ifdef HAVE_FSTATVFS
11710 "HAVE_FSTATVFS",
11711#endif
11712
Georg Brandl306336b2012-06-24 12:55:33 +020011713#ifdef HAVE_FTRUNCATE
11714 "HAVE_FTRUNCATE",
11715#endif
11716
Larry Hastings9cf065c2012-06-22 16:30:09 -070011717#ifdef HAVE_FUTIMENS
11718 "HAVE_FUTIMENS",
11719#endif
11720
11721#ifdef HAVE_FUTIMES
11722 "HAVE_FUTIMES",
11723#endif
11724
11725#ifdef HAVE_FUTIMESAT
11726 "HAVE_FUTIMESAT",
11727#endif
11728
11729#ifdef HAVE_LINKAT
11730 "HAVE_LINKAT",
11731#endif
11732
11733#ifdef HAVE_LCHFLAGS
11734 "HAVE_LCHFLAGS",
11735#endif
11736
11737#ifdef HAVE_LCHMOD
11738 "HAVE_LCHMOD",
11739#endif
11740
11741#ifdef HAVE_LCHOWN
11742 "HAVE_LCHOWN",
11743#endif
11744
11745#ifdef HAVE_LSTAT
11746 "HAVE_LSTAT",
11747#endif
11748
11749#ifdef HAVE_LUTIMES
11750 "HAVE_LUTIMES",
11751#endif
11752
11753#ifdef HAVE_MKDIRAT
11754 "HAVE_MKDIRAT",
11755#endif
11756
11757#ifdef HAVE_MKFIFOAT
11758 "HAVE_MKFIFOAT",
11759#endif
11760
11761#ifdef HAVE_MKNODAT
11762 "HAVE_MKNODAT",
11763#endif
11764
11765#ifdef HAVE_OPENAT
11766 "HAVE_OPENAT",
11767#endif
11768
11769#ifdef HAVE_READLINKAT
11770 "HAVE_READLINKAT",
11771#endif
11772
11773#ifdef HAVE_RENAMEAT
11774 "HAVE_RENAMEAT",
11775#endif
11776
11777#ifdef HAVE_SYMLINKAT
11778 "HAVE_SYMLINKAT",
11779#endif
11780
11781#ifdef HAVE_UNLINKAT
11782 "HAVE_UNLINKAT",
11783#endif
11784
11785#ifdef HAVE_UTIMENSAT
11786 "HAVE_UTIMENSAT",
11787#endif
11788
11789#ifdef MS_WINDOWS
11790 "MS_WINDOWS",
11791#endif
11792
11793 NULL
11794};
11795
11796
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011797PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011798INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011799{
Victor Stinner8c62be82010-05-06 00:08:46 +000011800 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011801 PyObject *list;
11802 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011803
Brian Curtin52173d42010-12-02 18:29:18 +000011804#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011805 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011806#endif
11807
Victor Stinner8c62be82010-05-06 00:08:46 +000011808 m = PyModule_Create(&posixmodule);
11809 if (m == NULL)
11810 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011811
Victor Stinner8c62be82010-05-06 00:08:46 +000011812 /* Initialize environ dictionary */
11813 v = convertenviron();
11814 Py_XINCREF(v);
11815 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11816 return NULL;
11817 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011818
Victor Stinner8c62be82010-05-06 00:08:46 +000011819 if (all_ins(m))
11820 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011821
Victor Stinner8c62be82010-05-06 00:08:46 +000011822 if (setup_confname_tables(m))
11823 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011824
Victor Stinner8c62be82010-05-06 00:08:46 +000011825 Py_INCREF(PyExc_OSError);
11826 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011827
Guido van Rossumb3d39562000-01-31 18:41:26 +000011828#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011829 if (posix_putenv_garbage == NULL)
11830 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011831#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011832
Victor Stinner8c62be82010-05-06 00:08:46 +000011833 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011834#if defined(HAVE_WAITID) && !defined(__APPLE__)
11835 waitid_result_desc.name = MODNAME ".waitid_result";
11836 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11837#endif
11838
Victor Stinner8c62be82010-05-06 00:08:46 +000011839 stat_result_desc.name = MODNAME ".stat_result";
11840 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11841 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11842 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11843 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11844 structseq_new = StatResultType.tp_new;
11845 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011846
Victor Stinner8c62be82010-05-06 00:08:46 +000011847 statvfs_result_desc.name = MODNAME ".statvfs_result";
11848 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011849#ifdef NEED_TICKS_PER_SECOND
11850# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011851 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011852# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011853 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011854# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011855 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011856# endif
11857#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011858
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011859#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011860 sched_param_desc.name = MODNAME ".sched_param";
11861 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11862 SchedParamType.tp_new = sched_param_new;
11863#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011864
11865 /* initialize TerminalSize_info */
11866 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011867 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011868#if defined(HAVE_WAITID) && !defined(__APPLE__)
11869 Py_INCREF((PyObject*) &WaitidResultType);
11870 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11871#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011872 Py_INCREF((PyObject*) &StatResultType);
11873 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11874 Py_INCREF((PyObject*) &StatVFSResultType);
11875 PyModule_AddObject(m, "statvfs_result",
11876 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011877
11878#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011879 Py_INCREF(&SchedParamType);
11880 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011881#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011882
Larry Hastings605a62d2012-06-24 04:33:36 -070011883 times_result_desc.name = MODNAME ".times_result";
11884 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11885 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11886
11887 uname_result_desc.name = MODNAME ".uname_result";
11888 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11889 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11890
Thomas Wouters477c8d52006-05-27 19:21:47 +000011891#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011892 /*
11893 * Step 2 of weak-linking support on Mac OS X.
11894 *
11895 * The code below removes functions that are not available on the
11896 * currently active platform.
11897 *
11898 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011899 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011900 * OSX 10.4.
11901 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011902#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011903 if (fstatvfs == NULL) {
11904 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11905 return NULL;
11906 }
11907 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011908#endif /* HAVE_FSTATVFS */
11909
11910#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011911 if (statvfs == NULL) {
11912 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11913 return NULL;
11914 }
11915 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011916#endif /* HAVE_STATVFS */
11917
11918# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011919 if (lchown == NULL) {
11920 if (PyObject_DelAttrString(m, "lchown") == -1) {
11921 return NULL;
11922 }
11923 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011924#endif /* HAVE_LCHOWN */
11925
11926
11927#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011928
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011929 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011930 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11931
Larry Hastings6fe20b32012-04-19 15:07:49 -070011932 billion = PyLong_FromLong(1000000000);
11933 if (!billion)
11934 return NULL;
11935
Larry Hastings9cf065c2012-06-22 16:30:09 -070011936 /* suppress "function not used" warnings */
11937 {
11938 int ignored;
11939 fd_specified("", -1);
11940 follow_symlinks_specified("", 1);
11941 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11942 dir_fd_converter(Py_None, &ignored);
11943 dir_fd_unavailable(Py_None, &ignored);
11944 }
11945
11946 /*
11947 * provide list of locally available functions
11948 * so os.py can populate support_* lists
11949 */
11950 list = PyList_New(0);
11951 if (!list)
11952 return NULL;
11953 for (trace = have_functions; *trace; trace++) {
11954 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11955 if (!unicode)
11956 return NULL;
11957 if (PyList_Append(list, unicode))
11958 return NULL;
11959 Py_DECREF(unicode);
11960 }
11961 PyModule_AddObject(m, "_have_functions", list);
11962
11963 initialized = 1;
11964
Victor Stinner8c62be82010-05-06 00:08:46 +000011965 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011966
Guido van Rossumb6775db1994-08-01 11:34:53 +000011967}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011968
11969#ifdef __cplusplus
11970}
11971#endif