blob: 6da030a371da6cf890637d8c9919e3b8a7495abc [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
417#define DEFAULT_DIR_FD AT_FDCWD
418#else
419#define DEFAULT_DIR_FD (-100)
420#endif
421
422static int
423_fd_converter(PyObject *o, int *p, int default_value) {
424 long long_value;
425 if (o == Py_None) {
426 *p = default_value;
427 return 1;
428 }
429 if (PyFloat_Check(o)) {
430 PyErr_SetString(PyExc_TypeError,
431 "integer argument expected, got float" );
432 return 0;
433 }
434 long_value = PyLong_AsLong(o);
435 if (long_value == -1 && PyErr_Occurred())
436 return 0;
437 if (long_value > INT_MAX) {
438 PyErr_SetString(PyExc_OverflowError,
439 "signed integer is greater than maximum");
440 return 0;
441 }
442 if (long_value < INT_MIN) {
443 PyErr_SetString(PyExc_OverflowError,
444 "signed integer is less than minimum");
445 return 0;
446 }
447 *p = (int)long_value;
448 return 1;
449}
450
451static int
452dir_fd_converter(PyObject *o, void *p) {
453 return _fd_converter(o, (int *)p, DEFAULT_DIR_FD);
454}
455
456
457
458/*
459 * A PyArg_ParseTuple "converter" function
460 * that handles filesystem paths in the manner
461 * preferred by the os module.
462 *
463 * path_converter accepts (Unicode) strings and their
464 * subclasses, and bytes and their subclasses. What
465 * it does with the argument depends on the platform:
466 *
467 * * On Windows, if we get a (Unicode) string we
468 * extract the wchar_t * and return it; if we get
469 * bytes we extract the char * and return that.
470 *
471 * * On all other platforms, strings are encoded
472 * to bytes using PyUnicode_FSConverter, then we
473 * extract the char * from the bytes object and
474 * return that.
475 *
476 * path_converter also optionally accepts signed
477 * integers (representing open file descriptors) instead
478 * of path strings.
479 *
480 * Input fields:
481 * path.nullable
482 * If nonzero, the path is permitted to be None.
483 * path.allow_fd
484 * If nonzero, the path is permitted to be a file handle
485 * (a signed int) instead of a string.
486 * path.function_name
487 * If non-NULL, path_converter will use that as the name
488 * of the function in error messages.
489 * (If path.argument_name is NULL it omits the function name.)
490 * path.argument_name
491 * If non-NULL, path_converter will use that as the name
492 * of the parameter in error messages.
493 * (If path.argument_name is NULL it uses "path".)
494 *
495 * Output fields:
496 * path.wide
497 * Points to the path if it was expressed as Unicode
498 * and was not encoded. (Only used on Windows.)
499 * path.narrow
500 * Points to the path if it was expressed as bytes,
501 * or it was Unicode and was encoded to bytes.
502 * path.fd
503 * Contains a file descriptor if path.accept_fd was true
504 * and the caller provided a signed integer instead of any
505 * sort of string.
506 *
507 * WARNING: if your "path" parameter is optional, and is
508 * unspecified, path_converter will never get called.
509 * So if you set allow_fd, you *MUST* initialize path.fd = -1
510 * yourself!
511 * path.length
512 * The length of the path in characters, if specified as
513 * a string.
514 * path.object
515 * The original object passed in.
516 * path.cleanup
517 * For internal use only. May point to a temporary object.
518 * (Pay no attention to the man behind the curtain.)
519 *
520 * At most one of path.wide or path.narrow will be non-NULL.
521 * If path was None and path.nullable was set,
522 * or if path was an integer and path.allow_fd was set,
523 * both path.wide and path.narrow will be NULL
524 * and path.length will be 0.
525 *
526 * path_converter takes care to not write to the path_t
527 * unless it's successful. However it must reset the
528 * "cleanup" field each time it's called.
529 *
530 * Use as follows:
531 * path_t path;
532 * memset(&path, 0, sizeof(path));
533 * PyArg_ParseTuple(args, "O&", path_converter, &path);
534 * // ... use values from path ...
535 * path_cleanup(&path);
536 *
537 * (Note that if PyArg_Parse fails you don't need to call
538 * path_cleanup(). However it is safe to do so.)
539 */
540typedef struct {
541 char *function_name;
542 char *argument_name;
543 int nullable;
544 int allow_fd;
545 wchar_t *wide;
546 char *narrow;
547 int fd;
548 Py_ssize_t length;
549 PyObject *object;
550 PyObject *cleanup;
551} path_t;
552
553static void
554path_cleanup(path_t *path) {
555 if (path->cleanup) {
556 Py_DECREF(path->cleanup);
557 path->cleanup = NULL;
558 }
559}
560
561static int
562path_converter(PyObject *o, void *p) {
563 path_t *path = (path_t *)p;
564 PyObject *unicode, *bytes;
565 Py_ssize_t length;
566 char *narrow;
567
568#define FORMAT_EXCEPTION(exc, fmt) \
569 PyErr_Format(exc, "%s%s" fmt, \
570 path->function_name ? path->function_name : "", \
571 path->function_name ? ": " : "", \
572 path->argument_name ? path->argument_name : "path")
573
574 /* Py_CLEANUP_SUPPORTED support */
575 if (o == NULL) {
576 path_cleanup(path);
577 return 1;
578 }
579
580 /* ensure it's always safe to call path_cleanup() */
581 path->cleanup = NULL;
582
583 if (o == Py_None) {
584 if (!path->nullable) {
585 FORMAT_EXCEPTION(PyExc_TypeError,
586 "can't specify None for %s argument");
587 return 0;
588 }
589 path->wide = NULL;
590 path->narrow = NULL;
591 path->length = 0;
592 path->object = o;
593 path->fd = -1;
594 return 1;
595 }
596
597 unicode = PyUnicode_FromObject(o);
598 if (unicode) {
599#ifdef MS_WINDOWS
600 wchar_t *wide;
601 length = PyUnicode_GET_SIZE(unicode);
602 if (length > 32767) {
603 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
604 Py_DECREF(unicode);
605 return 0;
606 }
607
608 wide = PyUnicode_AsUnicode(unicode);
609 if (!wide) {
610 Py_DECREF(unicode);
611 return 0;
612 }
613
614 path->wide = wide;
615 path->narrow = NULL;
616 path->length = length;
617 path->object = o;
618 path->fd = -1;
619 path->cleanup = unicode;
620 return Py_CLEANUP_SUPPORTED;
621#else
622 int converted = PyUnicode_FSConverter(unicode, &bytes);
623 Py_DECREF(unicode);
624 if (!converted)
625 bytes = NULL;
626#endif
627 }
628 else {
629 PyErr_Clear();
630 bytes = PyBytes_FromObject(o);
631 if (!bytes) {
632 PyErr_Clear();
633 if (path->allow_fd) {
634 int fd;
635 /*
636 * note: _fd_converter always permits None.
637 * but we've already done our None check.
638 * so o cannot be None at this point.
639 */
640 int result = _fd_converter(o, &fd, -1);
641 if (result) {
642 path->wide = NULL;
643 path->narrow = NULL;
644 path->length = 0;
645 path->object = o;
646 path->fd = fd;
647 return result;
648 }
649 }
650 }
651 }
652
653 if (!bytes) {
654 if (!PyErr_Occurred())
655 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
656 return 0;
657 }
658
659#ifdef MS_WINDOWS
660 if (win32_warn_bytes_api()) {
661 Py_DECREF(bytes);
662 return 0;
663 }
664#endif
665
666 length = PyBytes_GET_SIZE(bytes);
667#ifdef MS_WINDOWS
668 if (length > MAX_PATH) {
669 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
670 Py_DECREF(bytes);
671 return 0;
672 }
673#endif
674
675 narrow = PyBytes_AS_STRING(bytes);
676 if (length != strlen(narrow)) {
677 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
678 Py_DECREF(bytes);
679 return 0;
680 }
681
682 path->wide = NULL;
683 path->narrow = narrow;
684 path->length = length;
685 path->object = o;
686 path->fd = -1;
687 path->cleanup = bytes;
688 return Py_CLEANUP_SUPPORTED;
689}
690
691static void
692argument_unavailable_error(char *function_name, char *argument_name) {
693 PyErr_Format(PyExc_NotImplementedError,
694 "%s%s%s unavailable on this platform",
695 (function_name != NULL) ? function_name : "",
696 (function_name != NULL) ? ": ": "",
697 argument_name);
698}
699
700static int
701dir_fd_unavailable(PyObject *o, void *p) {
702 int *dir_fd = (int *)p;
703 int return_value = _fd_converter(o, dir_fd, DEFAULT_DIR_FD);
704 if (!return_value)
705 return 0;
706 if (*dir_fd == DEFAULT_DIR_FD)
707 return 1;
708 argument_unavailable_error(NULL, "dir_fd");
709 return 0;
710}
711
712static int
713fd_specified(char *function_name, int fd) {
714 if (fd == -1)
715 return 0;
716
717 argument_unavailable_error(function_name, "fd");
718 return 1;
719}
720
721static int
722follow_symlinks_specified(char *function_name, int follow_symlinks) {
723 if (follow_symlinks)
724 return 0;
725
726 argument_unavailable_error(function_name, "follow_symlinks");
727 return 1;
728}
729
730static int
731path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
732 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
733 PyErr_Format(PyExc_ValueError,
734 "%s: can't specify dir_fd without matching path",
735 function_name);
736 return 1;
737 }
738 return 0;
739}
740
741static int
742dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
743 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
744 PyErr_Format(PyExc_ValueError,
745 "%s: can't specify both dir_fd and fd",
746 function_name);
747 return 1;
748 }
749 return 0;
750}
751
752static int
753fd_and_follow_symlinks_invalid(char *function_name, int fd,
754 int follow_symlinks) {
755 if ((fd > 0) && (!follow_symlinks)) {
756 PyErr_Format(PyExc_ValueError,
757 "%s: cannot use fd and follow_symlinks together",
758 function_name);
759 return 1;
760 }
761 return 0;
762}
763
764static int
765dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
766 int follow_symlinks) {
767 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
768 PyErr_Format(PyExc_ValueError,
769 "%s: cannot use dir_fd and follow_symlinks together",
770 function_name);
771 return 1;
772 }
773 return 0;
774}
775
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200776/* A helper used by a number of POSIX-only functions */
777#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000778static int
779_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000780{
781#if !defined(HAVE_LARGEFILE_SUPPORT)
782 *((off_t*)addr) = PyLong_AsLong(arg);
783#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000784 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000785#endif
786 if (PyErr_Occurred())
787 return 0;
788 return 1;
789}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200790#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000791
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000792#if defined _MSC_VER && _MSC_VER >= 1400
793/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
794 * valid and throw an assertion if it isn't.
795 * Normally, an invalid fd is likely to be a C program error and therefore
796 * an assertion can be useful, but it does contradict the POSIX standard
797 * which for write(2) states:
798 * "Otherwise, -1 shall be returned and errno set to indicate the error."
799 * "[EBADF] The fildes argument is not a valid file descriptor open for
800 * writing."
801 * Furthermore, python allows the user to enter any old integer
802 * as a fd and should merely raise a python exception on error.
803 * The Microsoft CRT doesn't provide an official way to check for the
804 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000805 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000806 * internal structures involved.
807 * The structures below must be updated for each version of visual studio
808 * according to the file internal.h in the CRT source, until MS comes
809 * up with a less hacky way to do this.
810 * (all of this is to avoid globally modifying the CRT behaviour using
811 * _set_invalid_parameter_handler() and _CrtSetReportMode())
812 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000813/* The actual size of the structure is determined at runtime.
814 * Only the first items must be present.
815 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000816typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000817 intptr_t osfhnd;
818 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000819} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000820
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000821extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000822#define IOINFO_L2E 5
823#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
824#define IOINFO_ARRAYS 64
825#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
826#define FOPEN 0x01
827#define _NO_CONSOLE_FILENO (intptr_t)-2
828
829/* This function emulates what the windows CRT does to validate file handles */
830int
831_PyVerify_fd(int fd)
832{
Victor Stinner8c62be82010-05-06 00:08:46 +0000833 const int i1 = fd >> IOINFO_L2E;
834 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000835
Antoine Pitrou22e41552010-08-15 18:07:50 +0000836 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000837
Victor Stinner8c62be82010-05-06 00:08:46 +0000838 /* Determine the actual size of the ioinfo structure,
839 * as used by the CRT loaded in memory
840 */
841 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
842 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
843 }
844 if (sizeof_ioinfo == 0) {
845 /* This should not happen... */
846 goto fail;
847 }
848
849 /* See that it isn't a special CLEAR fileno */
850 if (fd != _NO_CONSOLE_FILENO) {
851 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
852 * we check pointer validity and other info
853 */
854 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
855 /* finally, check that the file is open */
856 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
857 if (info->osfile & FOPEN) {
858 return 1;
859 }
860 }
861 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000862 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000863 errno = EBADF;
864 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000865}
866
867/* the special case of checking dup2. The target fd must be in a sensible range */
868static int
869_PyVerify_fd_dup2(int fd1, int fd2)
870{
Victor Stinner8c62be82010-05-06 00:08:46 +0000871 if (!_PyVerify_fd(fd1))
872 return 0;
873 if (fd2 == _NO_CONSOLE_FILENO)
874 return 0;
875 if ((unsigned)fd2 < _NHANDLE_)
876 return 1;
877 else
878 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000879}
880#else
881/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
882#define _PyVerify_fd_dup2(A, B) (1)
883#endif
884
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000885#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000886/* The following structure was copied from
887 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
888 include doesn't seem to be present in the Windows SDK (at least as included
889 with Visual Studio Express). */
890typedef struct _REPARSE_DATA_BUFFER {
891 ULONG ReparseTag;
892 USHORT ReparseDataLength;
893 USHORT Reserved;
894 union {
895 struct {
896 USHORT SubstituteNameOffset;
897 USHORT SubstituteNameLength;
898 USHORT PrintNameOffset;
899 USHORT PrintNameLength;
900 ULONG Flags;
901 WCHAR PathBuffer[1];
902 } SymbolicLinkReparseBuffer;
903
904 struct {
905 USHORT SubstituteNameOffset;
906 USHORT SubstituteNameLength;
907 USHORT PrintNameOffset;
908 USHORT PrintNameLength;
909 WCHAR PathBuffer[1];
910 } MountPointReparseBuffer;
911
912 struct {
913 UCHAR DataBuffer[1];
914 } GenericReparseBuffer;
915 };
916} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
917
918#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
919 GenericReparseBuffer)
920#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
921
922static int
Brian Curtind25aef52011-06-13 15:16:04 -0500923win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000924{
925 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
926 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
927 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000928
929 if (0 == DeviceIoControl(
930 reparse_point_handle,
931 FSCTL_GET_REPARSE_POINT,
932 NULL, 0, /* in buffer */
933 target_buffer, sizeof(target_buffer),
934 &n_bytes_returned,
935 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500936 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000937
938 if (reparse_tag)
939 *reparse_tag = rdb->ReparseTag;
940
Brian Curtind25aef52011-06-13 15:16:04 -0500941 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000942}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100943
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000944#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000945
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000946/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000947#ifdef WITH_NEXT_FRAMEWORK
948/* On Darwin/MacOSX a shared library or framework has no access to
949** environ directly, we must obtain it with _NSGetEnviron().
950*/
951#include <crt_externs.h>
952static char **environ;
953#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000954extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000955#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000956
Barry Warsaw53699e91996-12-10 23:23:01 +0000957static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000958convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000959{
Victor Stinner8c62be82010-05-06 00:08:46 +0000960 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000961#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000962 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000963#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000964 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000965#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000966#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000967 APIRET rc;
968 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
969#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000970
Victor Stinner8c62be82010-05-06 00:08:46 +0000971 d = PyDict_New();
972 if (d == NULL)
973 return NULL;
974#ifdef WITH_NEXT_FRAMEWORK
975 if (environ == NULL)
976 environ = *_NSGetEnviron();
977#endif
978#ifdef MS_WINDOWS
979 /* _wenviron must be initialized in this way if the program is started
980 through main() instead of wmain(). */
981 _wgetenv(L"");
982 if (_wenviron == NULL)
983 return d;
984 /* This part ignores errors */
985 for (e = _wenviron; *e != NULL; e++) {
986 PyObject *k;
987 PyObject *v;
988 wchar_t *p = wcschr(*e, L'=');
989 if (p == NULL)
990 continue;
991 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
992 if (k == NULL) {
993 PyErr_Clear();
994 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000995 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000996 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
997 if (v == NULL) {
998 PyErr_Clear();
999 Py_DECREF(k);
1000 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001001 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001002 if (PyDict_GetItem(d, k) == NULL) {
1003 if (PyDict_SetItem(d, k, v) != 0)
1004 PyErr_Clear();
1005 }
1006 Py_DECREF(k);
1007 Py_DECREF(v);
1008 }
1009#else
1010 if (environ == NULL)
1011 return d;
1012 /* This part ignores errors */
1013 for (e = environ; *e != NULL; e++) {
1014 PyObject *k;
1015 PyObject *v;
1016 char *p = strchr(*e, '=');
1017 if (p == NULL)
1018 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001019 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001020 if (k == NULL) {
1021 PyErr_Clear();
1022 continue;
1023 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001024 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001025 if (v == NULL) {
1026 PyErr_Clear();
1027 Py_DECREF(k);
1028 continue;
1029 }
1030 if (PyDict_GetItem(d, k) == NULL) {
1031 if (PyDict_SetItem(d, k, v) != 0)
1032 PyErr_Clear();
1033 }
1034 Py_DECREF(k);
1035 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001036 }
1037#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001038#if defined(PYOS_OS2)
1039 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1040 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1041 PyObject *v = PyBytes_FromString(buffer);
1042 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1043 Py_DECREF(v);
1044 }
1045 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1046 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1047 PyObject *v = PyBytes_FromString(buffer);
1048 PyDict_SetItemString(d, "ENDLIBPATH", v);
1049 Py_DECREF(v);
1050 }
1051#endif
1052 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001053}
1054
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001055/* Set a POSIX-specific error from errno, and return NULL */
1056
Barry Warsawd58d7641998-07-23 16:14:40 +00001057static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001058posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001059{
Victor Stinner8c62be82010-05-06 00:08:46 +00001060 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061}
Barry Warsawd58d7641998-07-23 16:14:40 +00001062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001063posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001064{
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001066}
1067
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001068
Mark Hammondef8b6542001-05-13 08:04:26 +00001069static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001070posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001071{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001072 PyObject *name_str, *rc;
1073 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1074 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001075 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001076 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1077 name_str);
1078 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001079 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001080}
1081
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001082#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001083static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001084win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001085{
Victor Stinner8c62be82010-05-06 00:08:46 +00001086 /* XXX We should pass the function name along in the future.
1087 (winreg.c also wants to pass the function name.)
1088 This would however require an additional param to the
1089 Windows error object, which is non-trivial.
1090 */
1091 errno = GetLastError();
1092 if (filename)
1093 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1094 else
1095 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001096}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001097
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001098static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001099win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001100{
Victor Stinner8c62be82010-05-06 00:08:46 +00001101 /* XXX - see win32_error for comments on 'function' */
1102 errno = GetLastError();
1103 if (filename)
1104 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1105 else
1106 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001107}
1108
Victor Stinnereb5657a2011-09-30 01:44:27 +02001109static PyObject *
1110win32_error_object(char* function, PyObject* filename)
1111{
1112 /* XXX - see win32_error for comments on 'function' */
1113 errno = GetLastError();
1114 if (filename)
1115 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1116 PyExc_WindowsError,
1117 errno,
1118 filename);
1119 else
1120 return PyErr_SetFromWindowsErr(errno);
1121}
1122
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001123#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124
Larry Hastings9cf065c2012-06-22 16:30:09 -07001125/*
1126 * Some functions return Win32 errors, others only ever use posix_error
1127 * (this is for backwards compatibility with exceptions)
1128 */
1129static PyObject *
1130path_posix_error(char *function_name, path_t *path)
1131{
1132 if (path->narrow)
1133 return posix_error_with_filename(path->narrow);
1134 return posix_error();
1135}
1136
1137static PyObject *
1138path_error(char *function_name, path_t *path)
1139{
1140#ifdef MS_WINDOWS
1141 if (path->narrow)
1142 return win32_error(function_name, path->narrow);
1143 if (path->wide)
1144 return win32_error_unicode(function_name, path->wide);
1145 return win32_error(function_name, NULL);
1146#else
1147 return path_posix_error(function_name, path);
1148#endif
1149}
1150
Guido van Rossumd48f2521997-12-05 22:19:34 +00001151#if defined(PYOS_OS2)
1152/**********************************************************************
1153 * Helper Function to Trim and Format OS/2 Messages
1154 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001155static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001156os2_formatmsg(char *msgbuf, int msglen, char *reason)
1157{
1158 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1159
1160 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1161 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1162
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001163 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001164 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1165 }
1166
1167 /* Add Optional Reason Text */
1168 if (reason) {
1169 strcat(msgbuf, " : ");
1170 strcat(msgbuf, reason);
1171 }
1172}
1173
1174/**********************************************************************
1175 * Decode an OS/2 Operating System Error Code
1176 *
1177 * A convenience function to lookup an OS/2 error code and return a
1178 * text message we can use to raise a Python exception.
1179 *
1180 * Notes:
1181 * The messages for errors returned from the OS/2 kernel reside in
1182 * the file OSO001.MSG in the \OS2 directory hierarchy.
1183 *
1184 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001185static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001186os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1187{
1188 APIRET rc;
1189 ULONG msglen;
1190
1191 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1192 Py_BEGIN_ALLOW_THREADS
1193 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1194 errorcode, "oso001.msg", &msglen);
1195 Py_END_ALLOW_THREADS
1196
1197 if (rc == NO_ERROR)
1198 os2_formatmsg(msgbuf, msglen, reason);
1199 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001200 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001201 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001202
1203 return msgbuf;
1204}
1205
1206/* Set an OS/2-specific error and return NULL. OS/2 kernel
1207 errors are not in a global variable e.g. 'errno' nor are
1208 they congruent with posix error numbers. */
1209
Victor Stinner8c62be82010-05-06 00:08:46 +00001210static PyObject *
1211os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001212{
1213 char text[1024];
1214 PyObject *v;
1215
1216 os2_strerror(text, sizeof(text), code, "");
1217
1218 v = Py_BuildValue("(is)", code, text);
1219 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001220 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001221 Py_DECREF(v);
1222 }
1223 return NULL; /* Signal to Python that an Exception is Pending */
1224}
1225
1226#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001227
1228/* POSIX generic methods */
1229
Barry Warsaw53699e91996-12-10 23:23:01 +00001230static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001231posix_fildes(PyObject *fdobj, int (*func)(int))
1232{
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 int fd;
1234 int res;
1235 fd = PyObject_AsFileDescriptor(fdobj);
1236 if (fd < 0)
1237 return NULL;
1238 if (!_PyVerify_fd(fd))
1239 return posix_error();
1240 Py_BEGIN_ALLOW_THREADS
1241 res = (*func)(fd);
1242 Py_END_ALLOW_THREADS
1243 if (res < 0)
1244 return posix_error();
1245 Py_INCREF(Py_None);
1246 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001247}
Guido van Rossum21142a01999-01-08 21:05:37 +00001248
1249static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001250posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001251{
Victor Stinner8c62be82010-05-06 00:08:46 +00001252 PyObject *opath1 = NULL;
1253 char *path1;
1254 int res;
1255 if (!PyArg_ParseTuple(args, format,
1256 PyUnicode_FSConverter, &opath1))
1257 return NULL;
1258 path1 = PyBytes_AsString(opath1);
1259 Py_BEGIN_ALLOW_THREADS
1260 res = (*func)(path1);
1261 Py_END_ALLOW_THREADS
1262 if (res < 0)
1263 return posix_error_with_allocated_filename(opath1);
1264 Py_DECREF(opath1);
1265 Py_INCREF(Py_None);
1266 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267}
1268
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001270#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001271static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001272win32_1str(PyObject* args, char* func,
1273 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1274 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001275{
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001277 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001279
Victor Stinnereb5657a2011-09-30 01:44:27 +02001280 if (PyArg_ParseTuple(args, wformat, &uni))
1281 {
1282 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1283 if (wstr == NULL)
1284 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001285 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001286 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001287 Py_END_ALLOW_THREADS
1288 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001289 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001290 Py_INCREF(Py_None);
1291 return Py_None;
1292 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001293 PyErr_Clear();
1294
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 if (!PyArg_ParseTuple(args, format, &ansi))
1296 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001297 if (win32_warn_bytes_api())
1298 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 Py_BEGIN_ALLOW_THREADS
1300 result = funcA(ansi);
1301 Py_END_ALLOW_THREADS
1302 if (!result)
1303 return win32_error(func, ansi);
1304 Py_INCREF(Py_None);
1305 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001306
1307}
1308
1309/* This is a reimplementation of the C library's chdir function,
1310 but one that produces Win32 errors instead of DOS error codes.
1311 chdir is essentially a wrapper around SetCurrentDirectory; however,
1312 it also needs to set "magic" environment variables indicating
1313 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001314static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315win32_chdir(LPCSTR path)
1316{
Victor Stinner8c62be82010-05-06 00:08:46 +00001317 char new_path[MAX_PATH+1];
1318 int result;
1319 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001320
Victor Stinner8c62be82010-05-06 00:08:46 +00001321 if(!SetCurrentDirectoryA(path))
1322 return FALSE;
1323 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1324 if (!result)
1325 return FALSE;
1326 /* In the ANSI API, there should not be any paths longer
1327 than MAX_PATH. */
1328 assert(result <= MAX_PATH+1);
1329 if (strncmp(new_path, "\\\\", 2) == 0 ||
1330 strncmp(new_path, "//", 2) == 0)
1331 /* UNC path, nothing to do. */
1332 return TRUE;
1333 env[1] = new_path[0];
1334 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001335}
1336
1337/* The Unicode version differs from the ANSI version
1338 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001339static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340win32_wchdir(LPCWSTR path)
1341{
Victor Stinner8c62be82010-05-06 00:08:46 +00001342 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1343 int result;
1344 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001345
Victor Stinner8c62be82010-05-06 00:08:46 +00001346 if(!SetCurrentDirectoryW(path))
1347 return FALSE;
1348 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1349 if (!result)
1350 return FALSE;
1351 if (result > MAX_PATH+1) {
1352 new_path = malloc(result * sizeof(wchar_t));
1353 if (!new_path) {
1354 SetLastError(ERROR_OUTOFMEMORY);
1355 return FALSE;
1356 }
1357 result = GetCurrentDirectoryW(result, new_path);
1358 if (!result) {
1359 free(new_path);
1360 return FALSE;
1361 }
1362 }
1363 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1364 wcsncmp(new_path, L"//", 2) == 0)
1365 /* UNC path, nothing to do. */
1366 return TRUE;
1367 env[1] = new_path[0];
1368 result = SetEnvironmentVariableW(env, new_path);
1369 if (new_path != _new_path)
1370 free(new_path);
1371 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001372}
1373#endif
1374
Martin v. Löwis14694662006-02-03 12:54:16 +00001375#ifdef MS_WINDOWS
1376/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1377 - time stamps are restricted to second resolution
1378 - file modification times suffer from forth-and-back conversions between
1379 UTC and local time
1380 Therefore, we implement our own stat, based on the Win32 API directly.
1381*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001382#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001383
1384struct win32_stat{
1385 int st_dev;
1386 __int64 st_ino;
1387 unsigned short st_mode;
1388 int st_nlink;
1389 int st_uid;
1390 int st_gid;
1391 int st_rdev;
1392 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001393 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001394 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001395 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001396 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001397 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001398 int st_ctime_nsec;
1399};
1400
1401static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1402
1403static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001404FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001405{
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1407 /* Cannot simply cast and dereference in_ptr,
1408 since it might not be aligned properly */
1409 __int64 in;
1410 memcpy(&in, in_ptr, sizeof(in));
1411 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001412 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001413}
1414
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001416time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417{
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 /* XXX endianness */
1419 __int64 out;
1420 out = time_in + secs_between_epochs;
1421 out = out * 10000000 + nsec_in / 100;
1422 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001423}
1424
Martin v. Löwis14694662006-02-03 12:54:16 +00001425/* Below, we *know* that ugo+r is 0444 */
1426#if _S_IREAD != 0400
1427#error Unsupported C library
1428#endif
1429static int
1430attributes_to_mode(DWORD attr)
1431{
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 int m = 0;
1433 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1434 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1435 else
1436 m |= _S_IFREG;
1437 if (attr & FILE_ATTRIBUTE_READONLY)
1438 m |= 0444;
1439 else
1440 m |= 0666;
1441 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001442}
1443
1444static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001445attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001446{
Victor Stinner8c62be82010-05-06 00:08:46 +00001447 memset(result, 0, sizeof(*result));
1448 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1449 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1450 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1451 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1452 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001453 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001454 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001455 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1456 /* first clear the S_IFMT bits */
1457 result->st_mode ^= (result->st_mode & 0170000);
1458 /* now set the bits that make this a symlink */
1459 result->st_mode |= 0120000;
1460 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001461
Victor Stinner8c62be82010-05-06 00:08:46 +00001462 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001463}
1464
Guido van Rossumd8faa362007-04-27 19:54:29 +00001465static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001466attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001467{
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 HANDLE hFindFile;
1469 WIN32_FIND_DATAA FileData;
1470 hFindFile = FindFirstFileA(pszFile, &FileData);
1471 if (hFindFile == INVALID_HANDLE_VALUE)
1472 return FALSE;
1473 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001474 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001475 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001476 info->dwFileAttributes = FileData.dwFileAttributes;
1477 info->ftCreationTime = FileData.ftCreationTime;
1478 info->ftLastAccessTime = FileData.ftLastAccessTime;
1479 info->ftLastWriteTime = FileData.ftLastWriteTime;
1480 info->nFileSizeHigh = FileData.nFileSizeHigh;
1481 info->nFileSizeLow = FileData.nFileSizeLow;
1482/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001483 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1484 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001485 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001486}
1487
1488static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001489attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001490{
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 HANDLE hFindFile;
1492 WIN32_FIND_DATAW FileData;
1493 hFindFile = FindFirstFileW(pszFile, &FileData);
1494 if (hFindFile == INVALID_HANDLE_VALUE)
1495 return FALSE;
1496 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001497 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001498 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001499 info->dwFileAttributes = FileData.dwFileAttributes;
1500 info->ftCreationTime = FileData.ftCreationTime;
1501 info->ftLastAccessTime = FileData.ftLastAccessTime;
1502 info->ftLastWriteTime = FileData.ftLastWriteTime;
1503 info->nFileSizeHigh = FileData.nFileSizeHigh;
1504 info->nFileSizeLow = FileData.nFileSizeLow;
1505/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001506 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1507 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001509}
1510
Brian Curtind25aef52011-06-13 15:16:04 -05001511/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1512static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001513static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1514 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001515static int
Brian Curtind25aef52011-06-13 15:16:04 -05001516check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001517{
Brian Curtind25aef52011-06-13 15:16:04 -05001518 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001519 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1520 DWORD);
1521
Brian Curtind25aef52011-06-13 15:16:04 -05001522 /* only recheck */
1523 if (!has_GetFinalPathNameByHandle)
1524 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001525 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001526 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1527 "GetFinalPathNameByHandleA");
1528 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1529 "GetFinalPathNameByHandleW");
1530 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1531 Py_GetFinalPathNameByHandleW;
1532 }
1533 return has_GetFinalPathNameByHandle;
1534}
1535
1536static BOOL
1537get_target_path(HANDLE hdl, wchar_t **target_path)
1538{
1539 int buf_size, result_length;
1540 wchar_t *buf;
1541
1542 /* We have a good handle to the target, use it to determine
1543 the target path name (then we'll call lstat on it). */
1544 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1545 VOLUME_NAME_DOS);
1546 if(!buf_size)
1547 return FALSE;
1548
1549 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001550 if (!buf) {
1551 SetLastError(ERROR_OUTOFMEMORY);
1552 return FALSE;
1553 }
1554
Brian Curtind25aef52011-06-13 15:16:04 -05001555 result_length = Py_GetFinalPathNameByHandleW(hdl,
1556 buf, buf_size, VOLUME_NAME_DOS);
1557
1558 if(!result_length) {
1559 free(buf);
1560 return FALSE;
1561 }
1562
1563 if(!CloseHandle(hdl)) {
1564 free(buf);
1565 return FALSE;
1566 }
1567
1568 buf[result_length] = 0;
1569
1570 *target_path = buf;
1571 return TRUE;
1572}
1573
1574static int
1575win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1576 BOOL traverse);
1577static int
1578win32_xstat_impl(const char *path, struct win32_stat *result,
1579 BOOL traverse)
1580{
Victor Stinner26de69d2011-06-17 15:15:38 +02001581 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001582 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001583 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001584 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001585 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586 const char *dot;
1587
Brian Curtind25aef52011-06-13 15:16:04 -05001588 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001589 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1590 traverse reparse point. */
1591 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001592 }
1593
Brian Curtinf5e76d02010-11-24 13:14:05 +00001594 hFile = CreateFileA(
1595 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001596 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001597 0, /* share mode */
1598 NULL, /* security attributes */
1599 OPEN_EXISTING,
1600 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001601 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1602 Because of this, calls like GetFinalPathNameByHandle will return
1603 the symlink path agin and not the actual final path. */
1604 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1605 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001606 NULL);
1607
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001608 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609 /* Either the target doesn't exist, or we don't have access to
1610 get a handle to it. If the former, we need to return an error.
1611 If the latter, we can use attributes_from_dir. */
1612 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001613 return -1;
1614 /* Could not get attributes on open file. Fall back to
1615 reading the directory. */
1616 if (!attributes_from_dir(path, &info, &reparse_tag))
1617 /* Very strange. This should not fail now */
1618 return -1;
1619 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1620 if (traverse) {
1621 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001624 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 } else {
1627 if (!GetFileInformationByHandle(hFile, &info)) {
1628 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001629 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 }
1631 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001632 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1633 return -1;
1634
1635 /* Close the outer open file handle now that we're about to
1636 reopen it with different flags. */
1637 if (!CloseHandle(hFile))
1638 return -1;
1639
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001641 /* In order to call GetFinalPathNameByHandle we need to open
1642 the file without the reparse handling flag set. */
1643 hFile2 = CreateFileA(
1644 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1645 NULL, OPEN_EXISTING,
1646 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1647 NULL);
1648 if (hFile2 == INVALID_HANDLE_VALUE)
1649 return -1;
1650
1651 if (!get_target_path(hFile2, &target_path))
1652 return -1;
1653
1654 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001655 free(target_path);
1656 return code;
1657 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001658 } else
1659 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662
1663 /* Set S_IEXEC if it is an .exe, .bat, ... */
1664 dot = strrchr(path, '.');
1665 if (dot) {
1666 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1667 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1668 result->st_mode |= 0111;
1669 }
1670 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671}
1672
1673static int
Brian Curtind25aef52011-06-13 15:16:04 -05001674win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1675 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001676{
1677 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001678 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001679 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001680 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001681 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682 const wchar_t *dot;
1683
Brian Curtind25aef52011-06-13 15:16:04 -05001684 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001685 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1686 traverse reparse point. */
1687 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688 }
1689
Brian Curtinf5e76d02010-11-24 13:14:05 +00001690 hFile = CreateFileW(
1691 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001692 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 0, /* share mode */
1694 NULL, /* security attributes */
1695 OPEN_EXISTING,
1696 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001697 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1698 Because of this, calls like GetFinalPathNameByHandle will return
1699 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001700 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001701 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001702 NULL);
1703
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001704 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 /* Either the target doesn't exist, or we don't have access to
1706 get a handle to it. If the former, we need to return an error.
1707 If the latter, we can use attributes_from_dir. */
1708 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 return -1;
1710 /* Could not get attributes on open file. Fall back to
1711 reading the directory. */
1712 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1713 /* Very strange. This should not fail now */
1714 return -1;
1715 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1716 if (traverse) {
1717 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001718 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001719 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 } else {
1723 if (!GetFileInformationByHandle(hFile, &info)) {
1724 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001725 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 }
1727 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001728 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1729 return -1;
1730
1731 /* Close the outer open file handle now that we're about to
1732 reopen it with different flags. */
1733 if (!CloseHandle(hFile))
1734 return -1;
1735
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001736 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001737 /* In order to call GetFinalPathNameByHandle we need to open
1738 the file without the reparse handling flag set. */
1739 hFile2 = CreateFileW(
1740 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1741 NULL, OPEN_EXISTING,
1742 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1743 NULL);
1744 if (hFile2 == INVALID_HANDLE_VALUE)
1745 return -1;
1746
1747 if (!get_target_path(hFile2, &target_path))
1748 return -1;
1749
1750 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001751 free(target_path);
1752 return code;
1753 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001754 } else
1755 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001757 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001758
1759 /* Set S_IEXEC if it is an .exe, .bat, ... */
1760 dot = wcsrchr(path, '.');
1761 if (dot) {
1762 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1763 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1764 result->st_mode |= 0111;
1765 }
1766 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767}
1768
1769static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001770win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001772 /* Protocol violation: we explicitly clear errno, instead of
1773 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001774 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001775 errno = 0;
1776 return code;
1777}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001778
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001779static int
1780win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1781{
1782 /* Protocol violation: we explicitly clear errno, instead of
1783 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001784 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001785 errno = 0;
1786 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001787}
Brian Curtind25aef52011-06-13 15:16:04 -05001788/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001789
1790 In Posix, stat automatically traverses symlinks and returns the stat
1791 structure for the target. In Windows, the equivalent GetFileAttributes by
1792 default does not traverse symlinks and instead returns attributes for
1793 the symlink.
1794
1795 Therefore, win32_lstat will get the attributes traditionally, and
1796 win32_stat will first explicitly resolve the symlink target and then will
1797 call win32_lstat on that result.
1798
Ezio Melotti4969f702011-03-15 05:59:46 +02001799 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001800
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001801static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001802win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001803{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001804 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001805}
1806
Victor Stinner8c62be82010-05-06 00:08:46 +00001807static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001808win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001809{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001810 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001811}
1812
1813static int
1814win32_stat(const char* path, struct win32_stat *result)
1815{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001816 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001817}
1818
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001819static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001820win32_stat_w(const wchar_t* path, struct win32_stat *result)
1821{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001822 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001823}
1824
1825static int
1826win32_fstat(int file_number, struct win32_stat *result)
1827{
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 BY_HANDLE_FILE_INFORMATION info;
1829 HANDLE h;
1830 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001831
Victor Stinner8c62be82010-05-06 00:08:46 +00001832 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001833
Victor Stinner8c62be82010-05-06 00:08:46 +00001834 /* Protocol violation: we explicitly clear errno, instead of
1835 setting it to a POSIX error. Callers should use GetLastError. */
1836 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001837
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 if (h == INVALID_HANDLE_VALUE) {
1839 /* This is really a C library error (invalid file handle).
1840 We set the Win32 error to the closes one matching. */
1841 SetLastError(ERROR_INVALID_HANDLE);
1842 return -1;
1843 }
1844 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001845
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 type = GetFileType(h);
1847 if (type == FILE_TYPE_UNKNOWN) {
1848 DWORD error = GetLastError();
1849 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001850 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001851 }
1852 /* else: valid but unknown file */
1853 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001854
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 if (type != FILE_TYPE_DISK) {
1856 if (type == FILE_TYPE_CHAR)
1857 result->st_mode = _S_IFCHR;
1858 else if (type == FILE_TYPE_PIPE)
1859 result->st_mode = _S_IFIFO;
1860 return 0;
1861 }
1862
1863 if (!GetFileInformationByHandle(h, &info)) {
1864 return -1;
1865 }
1866
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001867 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001868 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001869 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1870 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001871}
1872
1873#endif /* MS_WINDOWS */
1874
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001875PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001876"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001877This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001878 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001879or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1880\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001881Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1882or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001883\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001884See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001885
1886static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 {"st_mode", "protection bits"},
1888 {"st_ino", "inode"},
1889 {"st_dev", "device"},
1890 {"st_nlink", "number of hard links"},
1891 {"st_uid", "user ID of owner"},
1892 {"st_gid", "group ID of owner"},
1893 {"st_size", "total size, in bytes"},
1894 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1895 {NULL, "integer time of last access"},
1896 {NULL, "integer time of last modification"},
1897 {NULL, "integer time of last change"},
1898 {"st_atime", "time of last access"},
1899 {"st_mtime", "time of last modification"},
1900 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001901 {"st_atime_ns", "time of last access in nanoseconds"},
1902 {"st_mtime_ns", "time of last modification in nanoseconds"},
1903 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001904#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001905 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001906#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001907#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001908 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001909#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001910#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001913#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001915#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001916#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001917 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001918#endif
1919#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001921#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001922 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001923};
1924
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001925#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001926#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001927#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001928#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001929#endif
1930
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001931#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001932#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1933#else
1934#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1935#endif
1936
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001937#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001938#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1939#else
1940#define ST_RDEV_IDX ST_BLOCKS_IDX
1941#endif
1942
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001943#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1944#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1945#else
1946#define ST_FLAGS_IDX ST_RDEV_IDX
1947#endif
1948
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001949#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001950#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001951#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001952#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001953#endif
1954
1955#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1956#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1957#else
1958#define ST_BIRTHTIME_IDX ST_GEN_IDX
1959#endif
1960
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001961static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 "stat_result", /* name */
1963 stat_result__doc__, /* doc */
1964 stat_result_fields,
1965 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001966};
1967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001969"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1970This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001971 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001972or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001973\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001974See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001975
1976static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 {"f_bsize", },
1978 {"f_frsize", },
1979 {"f_blocks", },
1980 {"f_bfree", },
1981 {"f_bavail", },
1982 {"f_files", },
1983 {"f_ffree", },
1984 {"f_favail", },
1985 {"f_flag", },
1986 {"f_namemax",},
1987 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001988};
1989
1990static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 "statvfs_result", /* name */
1992 statvfs_result__doc__, /* doc */
1993 statvfs_result_fields,
1994 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001995};
1996
Ross Lagerwall7807c352011-03-17 20:20:30 +02001997#if defined(HAVE_WAITID) && !defined(__APPLE__)
1998PyDoc_STRVAR(waitid_result__doc__,
1999"waitid_result: Result from waitid.\n\n\
2000This object may be accessed either as a tuple of\n\
2001 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2002or via the attributes si_pid, si_uid, and so on.\n\
2003\n\
2004See os.waitid for more information.");
2005
2006static PyStructSequence_Field waitid_result_fields[] = {
2007 {"si_pid", },
2008 {"si_uid", },
2009 {"si_signo", },
2010 {"si_status", },
2011 {"si_code", },
2012 {0}
2013};
2014
2015static PyStructSequence_Desc waitid_result_desc = {
2016 "waitid_result", /* name */
2017 waitid_result__doc__, /* doc */
2018 waitid_result_fields,
2019 5
2020};
2021static PyTypeObject WaitidResultType;
2022#endif
2023
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002024static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002025static PyTypeObject StatResultType;
2026static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002027#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002028static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002029#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002030static newfunc structseq_new;
2031
2032static PyObject *
2033statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2034{
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 PyStructSequence *result;
2036 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002037
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 result = (PyStructSequence*)structseq_new(type, args, kwds);
2039 if (!result)
2040 return NULL;
2041 /* If we have been initialized from a tuple,
2042 st_?time might be set to None. Initialize it
2043 from the int slots. */
2044 for (i = 7; i <= 9; i++) {
2045 if (result->ob_item[i+3] == Py_None) {
2046 Py_DECREF(Py_None);
2047 Py_INCREF(result->ob_item[i]);
2048 result->ob_item[i+3] = result->ob_item[i];
2049 }
2050 }
2051 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002052}
2053
2054
2055
2056/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002057static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002058
2059PyDoc_STRVAR(stat_float_times__doc__,
2060"stat_float_times([newval]) -> oldval\n\n\
2061Determine whether os.[lf]stat represents time stamps as float objects.\n\
2062If newval is True, future calls to stat() return floats, if it is False,\n\
2063future calls return ints. \n\
2064If newval is omitted, return the current setting.\n");
2065
2066static PyObject*
2067stat_float_times(PyObject* self, PyObject *args)
2068{
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 int newval = -1;
2070 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2071 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002072 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2073 "stat_float_times() is deprecated",
2074 1))
2075 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 if (newval == -1)
2077 /* Return old value */
2078 return PyBool_FromLong(_stat_float_times);
2079 _stat_float_times = newval;
2080 Py_INCREF(Py_None);
2081 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002082}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002083
Larry Hastings6fe20b32012-04-19 15:07:49 -07002084static PyObject *billion = NULL;
2085
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002086static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002087fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002088{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002089 PyObject *s = _PyLong_FromTime_t(sec);
2090 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2091 PyObject *s_in_ns = NULL;
2092 PyObject *ns_total = NULL;
2093 PyObject *float_s = NULL;
2094
2095 if (!(s && ns_fractional))
2096 goto exit;
2097
2098 s_in_ns = PyNumber_Multiply(s, billion);
2099 if (!s_in_ns)
2100 goto exit;
2101
2102 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2103 if (!ns_total)
2104 goto exit;
2105
Victor Stinner4195b5c2012-02-08 23:03:19 +01002106 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002107 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2108 if (!float_s)
2109 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002110 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002111 else {
2112 float_s = s;
2113 Py_INCREF(float_s);
2114 }
2115
2116 PyStructSequence_SET_ITEM(v, index, s);
2117 PyStructSequence_SET_ITEM(v, index+3, float_s);
2118 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2119 s = NULL;
2120 float_s = NULL;
2121 ns_total = NULL;
2122exit:
2123 Py_XDECREF(s);
2124 Py_XDECREF(ns_fractional);
2125 Py_XDECREF(s_in_ns);
2126 Py_XDECREF(ns_total);
2127 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002128}
2129
Tim Peters5aa91602002-01-30 05:46:57 +00002130/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002131 (used by posix_stat() and posix_fstat()) */
2132static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002133_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002134{
Victor Stinner8c62be82010-05-06 00:08:46 +00002135 unsigned long ansec, mnsec, cnsec;
2136 PyObject *v = PyStructSequence_New(&StatResultType);
2137 if (v == NULL)
2138 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002139
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002141#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002142 PyStructSequence_SET_ITEM(v, 1,
2143 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002144#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002145 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002146#endif
2147#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002148 PyStructSequence_SET_ITEM(v, 2,
2149 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002150#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002151 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002152#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002153 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
2154 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
2155 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00002156#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002157 PyStructSequence_SET_ITEM(v, 6,
2158 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002159#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002160 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002161#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002162
Martin v. Löwis14694662006-02-03 12:54:16 +00002163#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002164 ansec = st->st_atim.tv_nsec;
2165 mnsec = st->st_mtim.tv_nsec;
2166 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002167#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002168 ansec = st->st_atimespec.tv_nsec;
2169 mnsec = st->st_mtimespec.tv_nsec;
2170 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002171#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002172 ansec = st->st_atime_nsec;
2173 mnsec = st->st_mtime_nsec;
2174 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002175#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002176 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002177#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002178 fill_time(v, 7, st->st_atime, ansec);
2179 fill_time(v, 8, st->st_mtime, mnsec);
2180 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002181
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002182#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002183 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2184 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002185#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002186#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002187 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2188 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002189#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002190#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002191 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2192 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002193#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002194#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002195 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2196 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002197#endif
2198#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002199 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002200 PyObject *val;
2201 unsigned long bsec,bnsec;
2202 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002203#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002204 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002205#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002206 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002207#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002208 if (_stat_float_times) {
2209 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2210 } else {
2211 val = PyLong_FromLong((long)bsec);
2212 }
2213 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2214 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002215 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002216#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002217#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002218 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2219 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002220#endif
Fred Drake699f3522000-06-29 21:12:41 +00002221
Victor Stinner8c62be82010-05-06 00:08:46 +00002222 if (PyErr_Occurred()) {
2223 Py_DECREF(v);
2224 return NULL;
2225 }
Fred Drake699f3522000-06-29 21:12:41 +00002226
Victor Stinner8c62be82010-05-06 00:08:46 +00002227 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002228}
2229
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002230/* POSIX methods */
2231
Guido van Rossum94f6f721999-01-06 18:42:14 +00002232
2233static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002234posix_do_stat(char *function_name, path_t *path,
2235 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002236{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002237 STRUCT_STAT st;
2238 int result;
2239
2240#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2241 if (follow_symlinks_specified(function_name, follow_symlinks))
2242 return NULL;
2243#endif
2244
2245 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2246 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2247 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2248 return NULL;
2249
2250 Py_BEGIN_ALLOW_THREADS
2251 if (path->fd != -1)
2252 result = FSTAT(path->fd, &st);
2253 else
2254#ifdef MS_WINDOWS
2255 if (path->wide) {
2256 if (follow_symlinks)
2257 result = win32_stat_w(path->wide, &st);
2258 else
2259 result = win32_lstat_w(path->wide, &st);
2260 }
2261 else
2262#endif
2263#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2264 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2265 result = LSTAT(path->narrow, &st);
2266 else
2267#endif
2268#ifdef HAVE_FSTATAT
2269 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2270 result = fstatat(dir_fd, path->narrow, &st,
2271 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2272 else
2273#endif
2274 result = STAT(path->narrow, &st);
2275 Py_END_ALLOW_THREADS
2276
2277 if (result != 0)
2278 return path_error("stat", path);
2279
2280 return _pystat_fromstructstat(&st);
2281}
2282
2283PyDoc_STRVAR(posix_stat__doc__,
2284"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2285Perform a stat system call on the given path.\n\
2286\n\
2287path may be specified as either a string or as an open file descriptor.\n\
2288\n\
2289If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2290 and path should be relative; path will then be relative to that directory.\n\
2291 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2292 it will raise a NotImplementedError.\n\
2293If follow_symlinks is False, and the last element of the path is a symbolic\n\
2294 link, stat will examine the symbolic link itself instead of the file the\n\
2295 link points to.\n\
2296It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2297 an open file descriptor.");
2298
2299static PyObject *
2300posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2301{
2302 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2303 path_t path;
2304 int dir_fd = DEFAULT_DIR_FD;
2305 int follow_symlinks = 1;
2306 PyObject *return_value;
2307
2308 memset(&path, 0, sizeof(path));
2309 path.allow_fd = 1;
2310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2311 path_converter, &path,
2312#ifdef HAVE_FSTATAT
2313 dir_fd_converter, &dir_fd,
2314#else
2315 dir_fd_unavailable, &dir_fd,
2316#endif
2317 &follow_symlinks))
2318 return NULL;
2319 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2320 path_cleanup(&path);
2321 return return_value;
2322}
2323
2324PyDoc_STRVAR(posix_lstat__doc__,
2325"lstat(path, *, dir_fd=None) -> stat result\n\n\
2326Like stat(), but do not follow symbolic links.\n\
2327Equivalent to stat(path, follow_symlinks=False).");
2328
2329static PyObject *
2330posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2331{
2332 static char *keywords[] = {"path", "dir_fd", NULL};
2333 path_t path;
2334 int dir_fd = DEFAULT_DIR_FD;
2335 int follow_symlinks = 0;
2336 PyObject *return_value;
2337
2338 memset(&path, 0, sizeof(path));
2339 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2340 path_converter, &path,
2341#ifdef HAVE_FSTATAT
2342 dir_fd_converter, &dir_fd
2343#else
2344 dir_fd_unavailable, &dir_fd
2345#endif
2346 ))
2347 return NULL;
2348 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2349 path_cleanup(&path);
2350 return return_value;
2351}
2352
2353PyDoc_STRVAR(posix_access__doc__,
2354"access(path, mode, *, dir_fd=None, effective_ids=False,\
2355 follow_symlinks=True)\n\n\
2356Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2357False otherwise.\n\
2358\n\
2359If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2360 and path should be relative; path will then be relative to that directory.\n\
2361If effective_ids is True, access will use the effective uid/gid instead of\n\
2362 the real uid/gid.\n\
2363If follow_symlinks is False, and the last element of the path is a symbolic\n\
2364 link, access will examine the symbolic link itself instead of the file the\n\
2365 link points to.\n\
2366dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2367 on your platform. If they are unavailable, using them will raise a\n\
2368 NotImplementedError.\n\
2369\n\
2370Note that most operations will use the effective uid/gid, therefore this\n\
2371 routine can be used in a suid/sgid environment to test if the invoking user\n\
2372 has the specified access to the path.\n\
2373The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2374 of R_OK, W_OK, and X_OK.");
2375
2376static PyObject *
2377posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2378{
2379 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2380 "follow_symlinks", NULL};
2381 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002382 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002383 int dir_fd = DEFAULT_DIR_FD;
2384 int effective_ids = 0;
2385 int follow_symlinks = 1;
2386 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002387
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002388#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002389 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002390#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002391 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002392#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002393
2394 memset(&path, 0, sizeof(path));
2395 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2396 path_converter, &path, &mode,
2397#ifdef HAVE_FACCESSAT
2398 dir_fd_converter, &dir_fd,
2399#else
2400 dir_fd_unavailable, &dir_fd,
2401#endif
2402 &effective_ids, &follow_symlinks))
2403 return NULL;
2404
2405#ifndef HAVE_FACCESSAT
2406 if (follow_symlinks_specified("access", follow_symlinks))
2407 goto exit;
2408
2409 if (effective_ids) {
2410 argument_unavailable_error("access", "effective_ids");
2411 goto exit;
2412 }
2413#endif
2414
2415#ifdef MS_WINDOWS
2416 Py_BEGIN_ALLOW_THREADS
2417 if (path.wide != NULL)
2418 attr = GetFileAttributesW(path.wide);
2419 else
2420 attr = GetFileAttributesA(path.narrow);
2421 Py_END_ALLOW_THREADS
2422
2423 /*
2424 * Access is possible if
2425 * * we didn't get a -1, and
2426 * * write access wasn't requested,
2427 * * or the file isn't read-only,
2428 * * or it's a directory.
2429 * (Directories cannot be read-only on Windows.)
2430 */
2431 return_value = PyBool_FromLong(
2432 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002433 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002434 !(attr & FILE_ATTRIBUTE_READONLY) ||
2435 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2436#else
2437
2438 Py_BEGIN_ALLOW_THREADS
2439#ifdef HAVE_FACCESSAT
2440 if ((dir_fd != DEFAULT_DIR_FD) ||
2441 effective_ids ||
2442 !follow_symlinks) {
2443 int flags = 0;
2444 if (!follow_symlinks)
2445 flags |= AT_SYMLINK_NOFOLLOW;
2446 if (effective_ids)
2447 flags |= AT_EACCESS;
2448 result = faccessat(dir_fd, path.narrow, mode, flags);
2449 }
2450 else
2451#endif
2452 result = access(path.narrow, mode);
2453 Py_END_ALLOW_THREADS
2454 return_value = PyBool_FromLong(!result);
2455#endif
2456
2457#ifndef HAVE_FACCESSAT
2458exit:
2459#endif
2460 path_cleanup(&path);
2461 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002462}
2463
Guido van Rossumd371ff11999-01-25 16:12:23 +00002464#ifndef F_OK
2465#define F_OK 0
2466#endif
2467#ifndef R_OK
2468#define R_OK 4
2469#endif
2470#ifndef W_OK
2471#define W_OK 2
2472#endif
2473#ifndef X_OK
2474#define X_OK 1
2475#endif
2476
2477#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002478PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002479"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002480Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002481
2482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002483posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002484{
Victor Stinner8c62be82010-05-06 00:08:46 +00002485 int id;
2486 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002487
Victor Stinner8c62be82010-05-06 00:08:46 +00002488 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2489 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002490
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002491#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002492 /* file descriptor 0 only, the default input device (stdin) */
2493 if (id == 0) {
2494 ret = ttyname();
2495 }
2496 else {
2497 ret = NULL;
2498 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002499#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002500 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002501#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002502 if (ret == NULL)
2503 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002504 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002505}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002506#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002507
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002508#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002509PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002510"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002511Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002512
2513static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002514posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002515{
Victor Stinner8c62be82010-05-06 00:08:46 +00002516 char *ret;
2517 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002518
Greg Wardb48bc172000-03-01 21:51:56 +00002519#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002520 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002521#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002522 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002523#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002524 if (ret == NULL)
2525 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002526 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002527}
2528#endif
2529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002530PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002531"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002532Change the current working directory to the specified path.\n\
2533\n\
2534path may always be specified as a string.\n\
2535On some platforms, path may also be specified as an open file descriptor.\n\
2536 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002537
Barry Warsaw53699e91996-12-10 23:23:01 +00002538static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002540{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541 path_t path;
2542 int result;
2543 PyObject *return_value = NULL;
2544 static char *keywords[] = {"path", NULL};
2545
2546 memset(&path, 0, sizeof(path));
2547#ifdef HAVE_FCHDIR
2548 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002549#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002550 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2551 path_converter, &path
2552 ))
2553 return NULL;
2554
2555 Py_BEGIN_ALLOW_THREADS
2556#ifdef MS_WINDOWS
2557 if (path.wide)
2558 result = win32_wchdir(path.wide);
2559 else
2560 result = win32_chdir(path.narrow);
2561 result = !result; /* on unix, success = 0, on windows, success = !0 */
2562#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2563 result = _chdir2(path.narrow);
2564#else
2565#ifdef HAVE_FCHDIR
2566 if (path.fd != -1)
2567 result = fchdir(path.fd);
2568 else
2569#endif
2570 result = chdir(path.narrow);
2571#endif
2572 Py_END_ALLOW_THREADS
2573
2574 if (result) {
2575 return_value = path_error("chdir", &path);
2576 goto exit;
2577 }
2578
2579 return_value = Py_None;
2580 Py_INCREF(Py_None);
2581
2582exit:
2583 path_cleanup(&path);
2584 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002585}
2586
Fred Drake4d1e64b2002-04-15 19:40:07 +00002587#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002588PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002589"fchdir(fd)\n\n\
2590Change to the directory of the given file descriptor. fd must be\n\
2591opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002592
2593static PyObject *
2594posix_fchdir(PyObject *self, PyObject *fdobj)
2595{
Victor Stinner8c62be82010-05-06 00:08:46 +00002596 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002597}
2598#endif /* HAVE_FCHDIR */
2599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002601PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002602"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2603Change the access permissions of a file.\n\
2604\n\
2605path may always be specified as a string.\n\
2606On some platforms, path may also be specified as an open file descriptor.\n\
2607 If this functionality is unavailable, using it raises an exception.\n\
2608If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2609 and path should be relative; path will then be relative to that directory.\n\
2610If follow_symlinks is False, and the last element of the path is a symbolic\n\
2611 link, chmod will modify the symbolic link itself instead of the file the\n\
2612 link points to.\n\
2613It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2614 an open file descriptor.\n\
2615dir_fd and follow_symlinks may not be implemented on your platform.\n\
2616 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002617
Barry Warsaw53699e91996-12-10 23:23:01 +00002618static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002620{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621 path_t path;
2622 int mode;
2623 int dir_fd = DEFAULT_DIR_FD;
2624 int follow_symlinks = 1;
2625 int result;
2626 PyObject *return_value = NULL;
2627 static char *keywords[] = {"path", "mode", "dir_fd",
2628 "follow_symlinks", NULL};
2629
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002630#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002631 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002633
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634#ifdef HAVE_FCHMODAT
2635 int fchmodat_nofollow_unsupported = 0;
2636#endif
2637
2638 memset(&path, 0, sizeof(path));
2639#ifdef HAVE_FCHMOD
2640 path.allow_fd = 1;
2641#endif
2642 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2643 path_converter, &path,
2644 &mode,
2645#ifdef HAVE_FCHMODAT
2646 dir_fd_converter, &dir_fd,
2647#else
2648 dir_fd_unavailable, &dir_fd,
2649#endif
2650 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002651 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002652
2653#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2654 if (follow_symlinks_specified("chmod", follow_symlinks))
2655 goto exit;
2656#endif
2657
2658#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002659 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002660 if (path.wide)
2661 attr = GetFileAttributesW(path.wide);
2662 else
2663 attr = GetFileAttributesA(path.narrow);
2664 if (attr == 0xFFFFFFFF)
2665 result = 0;
2666 else {
2667 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 attr &= ~FILE_ATTRIBUTE_READONLY;
2669 else
2670 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 if (path.wide)
2672 result = SetFileAttributesW(path.wide, attr);
2673 else
2674 result = SetFileAttributesA(path.narrow, attr);
2675 }
2676 Py_END_ALLOW_THREADS
2677
2678 if (!result) {
2679 return_value = win32_error_object("chmod", path.object);
2680 goto exit;
2681 }
2682#else /* MS_WINDOWS */
2683 Py_BEGIN_ALLOW_THREADS
2684#ifdef HAVE_FCHMOD
2685 if (path.fd != -1)
2686 result = fchmod(path.fd, mode);
2687 else
2688#endif
2689#ifdef HAVE_LCHMOD
2690 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2691 result = lchmod(path.narrow, mode);
2692 else
2693#endif
2694#ifdef HAVE_FCHMODAT
2695 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2696 /*
2697 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2698 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002699 * and then says it isn't implemented yet.
2700 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002701 *
2702 * Once it is supported, os.chmod will automatically
2703 * support dir_fd and follow_symlinks=False. (Hopefully.)
2704 * Until then, we need to be careful what exception we raise.
2705 */
2706 result = fchmodat(dir_fd, path.narrow, mode,
2707 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2708 /*
2709 * But wait! We can't throw the exception without allowing threads,
2710 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2711 */
2712 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002713 result &&
2714 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2715 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002716 }
2717 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002718#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002719 result = chmod(path.narrow, mode);
2720 Py_END_ALLOW_THREADS
2721
2722 if (result) {
2723#ifdef HAVE_FCHMODAT
2724 if (fchmodat_nofollow_unsupported) {
2725 if (dir_fd != DEFAULT_DIR_FD)
2726 dir_fd_and_follow_symlinks_invalid("chmod",
2727 dir_fd, follow_symlinks);
2728 else
2729 follow_symlinks_specified("chmod", follow_symlinks);
2730 }
2731 else
2732#endif
2733 return_value = path_error("chmod", &path);
2734 goto exit;
2735 }
2736#endif
2737
2738 Py_INCREF(Py_None);
2739 return_value = Py_None;
2740exit:
2741 path_cleanup(&path);
2742 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002743}
2744
Larry Hastings9cf065c2012-06-22 16:30:09 -07002745
Christian Heimes4e30a842007-11-30 22:12:06 +00002746#ifdef HAVE_FCHMOD
2747PyDoc_STRVAR(posix_fchmod__doc__,
2748"fchmod(fd, mode)\n\n\
2749Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002750descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002751
2752static PyObject *
2753posix_fchmod(PyObject *self, PyObject *args)
2754{
Victor Stinner8c62be82010-05-06 00:08:46 +00002755 int fd, mode, res;
2756 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2757 return NULL;
2758 Py_BEGIN_ALLOW_THREADS
2759 res = fchmod(fd, mode);
2760 Py_END_ALLOW_THREADS
2761 if (res < 0)
2762 return posix_error();
2763 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002764}
2765#endif /* HAVE_FCHMOD */
2766
2767#ifdef HAVE_LCHMOD
2768PyDoc_STRVAR(posix_lchmod__doc__,
2769"lchmod(path, mode)\n\n\
2770Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002771affects the link itself rather than the target.\n\
2772Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002773
2774static PyObject *
2775posix_lchmod(PyObject *self, PyObject *args)
2776{
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 PyObject *opath;
2778 char *path;
2779 int i;
2780 int res;
2781 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2782 &opath, &i))
2783 return NULL;
2784 path = PyBytes_AsString(opath);
2785 Py_BEGIN_ALLOW_THREADS
2786 res = lchmod(path, i);
2787 Py_END_ALLOW_THREADS
2788 if (res < 0)
2789 return posix_error_with_allocated_filename(opath);
2790 Py_DECREF(opath);
2791 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002792}
2793#endif /* HAVE_LCHMOD */
2794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002795
Thomas Wouterscf297e42007-02-23 15:07:44 +00002796#ifdef HAVE_CHFLAGS
2797PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798"chflags(path, flags, *, follow_symlinks=True)\n\n\
2799Set file flags.\n\
2800\n\
2801If follow_symlinks is False, and the last element of the path is a symbolic\n\
2802 link, chflags will change flags on the symbolic link itself instead of the\n\
2803 file the link points to.\n\
2804follow_symlinks may not be implemented on your platform. If it is\n\
2805unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002806
2807static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002809{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002810 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002811 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002812 int follow_symlinks = 1;
2813 int result;
2814 PyObject *return_value;
2815 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2816
2817 memset(&path, 0, sizeof(path));
2818 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2819 path_converter, &path,
2820 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002821 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822
2823#ifndef HAVE_LCHFLAGS
2824 if (follow_symlinks_specified("chflags", follow_symlinks))
2825 goto exit;
2826#endif
2827
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829#ifdef HAVE_LCHFLAGS
2830 if (!follow_symlinks)
2831 result = lchflags(path.narrow, flags);
2832 else
2833#endif
2834 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002835 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002836
2837 if (result) {
2838 return_value = path_posix_error("chflags", &path);
2839 goto exit;
2840 }
2841
2842 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002843 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844
2845exit:
2846 path_cleanup(&path);
2847 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002848}
2849#endif /* HAVE_CHFLAGS */
2850
2851#ifdef HAVE_LCHFLAGS
2852PyDoc_STRVAR(posix_lchflags__doc__,
2853"lchflags(path, flags)\n\n\
2854Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855This function will not follow symbolic links.\n\
2856Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002857
2858static PyObject *
2859posix_lchflags(PyObject *self, PyObject *args)
2860{
Victor Stinner8c62be82010-05-06 00:08:46 +00002861 PyObject *opath;
2862 char *path;
2863 unsigned long flags;
2864 int res;
2865 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2866 PyUnicode_FSConverter, &opath, &flags))
2867 return NULL;
2868 path = PyBytes_AsString(opath);
2869 Py_BEGIN_ALLOW_THREADS
2870 res = lchflags(path, flags);
2871 Py_END_ALLOW_THREADS
2872 if (res < 0)
2873 return posix_error_with_allocated_filename(opath);
2874 Py_DECREF(opath);
2875 Py_INCREF(Py_None);
2876 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002877}
2878#endif /* HAVE_LCHFLAGS */
2879
Martin v. Löwis244edc82001-10-04 22:44:26 +00002880#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002881PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002882"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002883Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002884
2885static PyObject *
2886posix_chroot(PyObject *self, PyObject *args)
2887{
Victor Stinner8c62be82010-05-06 00:08:46 +00002888 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002889}
2890#endif
2891
Guido van Rossum21142a01999-01-08 21:05:37 +00002892#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002893PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002894"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002895force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002896
2897static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002898posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002899{
Stefan Krah0e803b32010-11-26 16:16:47 +00002900 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002901}
2902#endif /* HAVE_FSYNC */
2903
Ross Lagerwall7807c352011-03-17 20:20:30 +02002904#ifdef HAVE_SYNC
2905PyDoc_STRVAR(posix_sync__doc__,
2906"sync()\n\n\
2907Force write of everything to disk.");
2908
2909static PyObject *
2910posix_sync(PyObject *self, PyObject *noargs)
2911{
2912 Py_BEGIN_ALLOW_THREADS
2913 sync();
2914 Py_END_ALLOW_THREADS
2915 Py_RETURN_NONE;
2916}
2917#endif
2918
Guido van Rossum21142a01999-01-08 21:05:37 +00002919#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002920
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002921#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002922extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2923#endif
2924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002926"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002927force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002928 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002929
2930static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002931posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002932{
Stefan Krah0e803b32010-11-26 16:16:47 +00002933 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002934}
2935#endif /* HAVE_FDATASYNC */
2936
2937
Fredrik Lundh10723342000-07-10 16:38:09 +00002938#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002939PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002940"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2941Change the owner and group id of path to the numeric uid and gid.\n\
2942\n\
2943path may always be specified as a string.\n\
2944On some platforms, path may also be specified as an open file descriptor.\n\
2945 If this functionality is unavailable, using it raises an exception.\n\
2946If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2947 and path should be relative; path will then be relative to that directory.\n\
2948If follow_symlinks is False, and the last element of the path is a symbolic\n\
2949 link, chown will modify the symbolic link itself instead of the file the\n\
2950 link points to.\n\
2951It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2952 an open file descriptor.\n\
2953dir_fd and follow_symlinks may not be implemented on your platform.\n\
2954 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002955
Barry Warsaw53699e91996-12-10 23:23:01 +00002956static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002957posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002958{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002959 path_t path;
2960 long uid_l, gid_l;
2961 uid_t uid;
2962 gid_t gid;
2963 int dir_fd = DEFAULT_DIR_FD;
2964 int follow_symlinks = 1;
2965 int result;
2966 PyObject *return_value = NULL;
2967 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2968 "follow_symlinks", NULL};
2969
2970 memset(&path, 0, sizeof(path));
2971#ifdef HAVE_FCHOWN
2972 path.allow_fd = 1;
2973#endif
2974 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2975 path_converter, &path,
2976 &uid_l, &gid_l,
2977#ifdef HAVE_FCHOWNAT
2978 dir_fd_converter, &dir_fd,
2979#else
2980 dir_fd_unavailable, &dir_fd,
2981#endif
2982 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984
2985#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2986 if (follow_symlinks_specified("chown", follow_symlinks))
2987 goto exit;
2988#endif
2989 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2990 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2991 goto exit;
2992
2993#ifdef __APPLE__
2994 /*
2995 * This is for Mac OS X 10.3, which doesn't have lchown.
2996 * (But we still have an lchown symbol because of weak-linking.)
2997 * It doesn't have fchownat either. So there's no possibility
2998 * of a graceful failover.
2999 */
3000 if ((!follow_symlinks) && (lchown == NULL)) {
3001 follow_symlinks_specified("chown", follow_symlinks);
3002 goto exit;
3003 }
3004#endif
3005
Victor Stinner8c62be82010-05-06 00:08:46 +00003006 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003007 uid = (uid_t)uid_l;
3008 gid = (uid_t)gid_l;
3009#ifdef HAVE_FCHOWN
3010 if (path.fd != -1)
3011 result = fchown(path.fd, uid, gid);
3012 else
3013#endif
3014#ifdef HAVE_LCHOWN
3015 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3016 result = lchown(path.narrow, uid, gid);
3017 else
3018#endif
3019#ifdef HAVE_FCHOWNAT
3020 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3021 result = fchownat(dir_fd, path.narrow, uid, gid,
3022 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3023 else
3024#endif
3025 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003026 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003027
3028 if (result) {
3029 return_value = path_posix_error("chown", &path);
3030 goto exit;
3031 }
3032
3033 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003034 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003035
3036exit:
3037 path_cleanup(&path);
3038 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003039}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003040#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003041
Christian Heimes4e30a842007-11-30 22:12:06 +00003042#ifdef HAVE_FCHOWN
3043PyDoc_STRVAR(posix_fchown__doc__,
3044"fchown(fd, uid, gid)\n\n\
3045Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003046fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003047
3048static PyObject *
3049posix_fchown(PyObject *self, PyObject *args)
3050{
Victor Stinner8c62be82010-05-06 00:08:46 +00003051 int fd;
3052 long uid, gid;
3053 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02003054 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003055 return NULL;
3056 Py_BEGIN_ALLOW_THREADS
3057 res = fchown(fd, (uid_t) uid, (gid_t) gid);
3058 Py_END_ALLOW_THREADS
3059 if (res < 0)
3060 return posix_error();
3061 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003062}
3063#endif /* HAVE_FCHOWN */
3064
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003065#ifdef HAVE_LCHOWN
3066PyDoc_STRVAR(posix_lchown__doc__,
3067"lchown(path, uid, gid)\n\n\
3068Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003069This function will not follow symbolic links.\n\
3070Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003071
3072static PyObject *
3073posix_lchown(PyObject *self, PyObject *args)
3074{
Victor Stinner8c62be82010-05-06 00:08:46 +00003075 PyObject *opath;
3076 char *path;
3077 long uid, gid;
3078 int res;
3079 if (!PyArg_ParseTuple(args, "O&ll:lchown",
3080 PyUnicode_FSConverter, &opath,
3081 &uid, &gid))
3082 return NULL;
3083 path = PyBytes_AsString(opath);
3084 Py_BEGIN_ALLOW_THREADS
3085 res = lchown(path, (uid_t) uid, (gid_t) gid);
3086 Py_END_ALLOW_THREADS
3087 if (res < 0)
3088 return posix_error_with_allocated_filename(opath);
3089 Py_DECREF(opath);
3090 Py_INCREF(Py_None);
3091 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003092}
3093#endif /* HAVE_LCHOWN */
3094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003095
Guido van Rossum36bc6801995-06-14 22:54:23 +00003096#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003097static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003098posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003099{
Victor Stinner8c62be82010-05-06 00:08:46 +00003100 char buf[1026];
3101 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003102
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003103#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003104 if (!use_bytes) {
3105 wchar_t wbuf[1026];
3106 wchar_t *wbuf2 = wbuf;
3107 PyObject *resobj;
3108 DWORD len;
3109 Py_BEGIN_ALLOW_THREADS
3110 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3111 /* If the buffer is large enough, len does not include the
3112 terminating \0. If the buffer is too small, len includes
3113 the space needed for the terminator. */
3114 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3115 wbuf2 = malloc(len * sizeof(wchar_t));
3116 if (wbuf2)
3117 len = GetCurrentDirectoryW(len, wbuf2);
3118 }
3119 Py_END_ALLOW_THREADS
3120 if (!wbuf2) {
3121 PyErr_NoMemory();
3122 return NULL;
3123 }
3124 if (!len) {
3125 if (wbuf2 != wbuf) free(wbuf2);
3126 return win32_error("getcwdu", NULL);
3127 }
3128 resobj = PyUnicode_FromWideChar(wbuf2, len);
3129 if (wbuf2 != wbuf) free(wbuf2);
3130 return resobj;
3131 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003132
3133 if (win32_warn_bytes_api())
3134 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003135#endif
3136
Victor Stinner8c62be82010-05-06 00:08:46 +00003137 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003138#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003139 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003140#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003141 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003142#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003143 Py_END_ALLOW_THREADS
3144 if (res == NULL)
3145 return posix_error();
3146 if (use_bytes)
3147 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003148 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003149}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003150
3151PyDoc_STRVAR(posix_getcwd__doc__,
3152"getcwd() -> path\n\n\
3153Return a unicode string representing the current working directory.");
3154
3155static PyObject *
3156posix_getcwd_unicode(PyObject *self)
3157{
3158 return posix_getcwd(0);
3159}
3160
3161PyDoc_STRVAR(posix_getcwdb__doc__,
3162"getcwdb() -> path\n\n\
3163Return a bytes string representing the current working directory.");
3164
3165static PyObject *
3166posix_getcwd_bytes(PyObject *self)
3167{
3168 return posix_getcwd(1);
3169}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003170#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003171
Larry Hastings9cf065c2012-06-22 16:30:09 -07003172#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3173#define HAVE_LINK 1
3174#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175
Guido van Rossumb6775db1994-08-01 11:34:53 +00003176#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003177PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003178"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3179Create a hard link to a file.\n\
3180\n\
3181If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3182 descriptor open to a directory, and the respective path string (src or dst)\n\
3183 should be relative; the path will then be relative to that directory.\n\
3184If follow_symlinks is False, and the last element of src is a symbolic\n\
3185 link, link will create a link to the symbolic link itself instead of the\n\
3186 file the link points to.\n\
3187src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3188 platform. If they are unavailable, using them will raise a\n\
3189 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003190
Barry Warsaw53699e91996-12-10 23:23:01 +00003191static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003193{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194 path_t src, dst;
3195 int src_dir_fd = DEFAULT_DIR_FD;
3196 int dst_dir_fd = DEFAULT_DIR_FD;
3197 int follow_symlinks = 1;
3198 PyObject *return_value = NULL;
3199 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3200 "follow_symlinks", NULL};
3201#ifdef MS_WINDOWS
3202 BOOL result;
3203#else
3204 int result;
3205#endif
3206
3207 memset(&src, 0, sizeof(src));
3208 memset(&dst, 0, sizeof(dst));
3209 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3210 path_converter, &src,
3211 path_converter, &dst,
3212 dir_fd_converter, &src_dir_fd,
3213 dir_fd_converter, &dst_dir_fd,
3214 &follow_symlinks))
3215 return NULL;
3216
3217#ifndef HAVE_LINKAT
3218 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3219 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3220 goto exit;
3221 }
3222#endif
3223
3224 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3225 PyErr_SetString(PyExc_NotImplementedError,
3226 "link: src and dst must be the same type");
3227 goto exit;
3228 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003229
Brian Curtin1b9df392010-11-24 20:24:31 +00003230#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003231 Py_BEGIN_ALLOW_THREADS
3232 if (src.wide)
3233 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3234 else
3235 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3236 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003237
Larry Hastings9cf065c2012-06-22 16:30:09 -07003238 if (!result) {
3239 return_value = win32_error_object("link", dst.object);
3240 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003241 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003242#else
3243 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003244#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003245 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3246 (dst_dir_fd != DEFAULT_DIR_FD) ||
3247 (!follow_symlinks))
3248 result = linkat(src_dir_fd, src.narrow,
3249 dst_dir_fd, dst.narrow,
3250 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3251 else
3252#endif
3253 result = link(src.narrow, dst.narrow);
3254 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003255
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256 if (result) {
3257 return_value = path_error("link", &dst);
3258 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003259 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003260#endif
3261
3262 return_value = Py_None;
3263 Py_INCREF(Py_None);
3264
3265exit:
3266 path_cleanup(&src);
3267 path_cleanup(&dst);
3268 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003269}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270#endif
3271
Brian Curtin1b9df392010-11-24 20:24:31 +00003272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003273
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003274PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003275"listdir(path='.') -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003276Return a list containing the names of the entries in the directory.\n\
3277\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003278The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003279entries '.' and '..' even if they are present in the directory.\n\
3280\n\
3281path can always be specified as a string.\n\
3282On some platforms, path may also be specified as an open file descriptor.\n\
3283 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284
Barry Warsaw53699e91996-12-10 23:23:01 +00003285static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003286posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003287{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003288 path_t path;
3289 PyObject *list = NULL;
3290 static char *keywords[] = {"path", NULL};
3291 int fd = -1;
3292
3293#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3294 PyObject *v;
3295 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3296 BOOL result;
3297 WIN32_FIND_DATA FileData;
3298 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3299 char *bufptr = namebuf;
3300 /* only claim to have space for MAX_PATH */
3301 Py_ssize_t len = sizeof(namebuf)-5;
3302 PyObject *po = NULL;
3303 wchar_t *wnamebuf = NULL;
3304#elif defined(PYOS_OS2)
3305#ifndef MAX_PATH
3306#define MAX_PATH CCHMAXPATH
3307#endif
3308 char *pt;
3309 PyObject *v;
3310 char namebuf[MAX_PATH+5];
3311 HDIR hdir = 1;
3312 ULONG srchcnt = 1;
3313 FILEFINDBUF3 ep;
3314 APIRET rc;
3315#else
3316 PyObject *v;
3317 DIR *dirp = NULL;
3318 struct dirent *ep;
3319 int arg_is_unicode = 1;
3320#endif
3321
3322 memset(&path, 0, sizeof(path));
3323 path.nullable = 1;
3324#ifdef HAVE_FDOPENDIR
3325 path.allow_fd = 1;
3326 path.fd = -1;
3327#endif
3328 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3329 path_converter, &path
3330 ))
3331 return NULL;
3332
Victor Stinner8c62be82010-05-06 00:08:46 +00003333 /* XXX Should redo this putting the (now four) versions of opendir
3334 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003335#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003337 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003338 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003339
Larry Hastings9cf065c2012-06-22 16:30:09 -07003340 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003341 po_wchars = L".";
3342 len = 1;
3343 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344 po_wchars = path.wide;
3345 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003346 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003347 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3349 if (!wnamebuf) {
3350 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003351 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003352 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003353 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003355 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 if (wch != L'/' && wch != L'\\' && wch != L':')
3357 wnamebuf[len++] = L'\\';
3358 wcscpy(wnamebuf + len, L"*.*");
3359 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003360 if ((list = PyList_New(0)) == NULL) {
3361 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003363 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003365 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003366 if (hFindFile == INVALID_HANDLE_VALUE) {
3367 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368 if (error == ERROR_FILE_NOT_FOUND)
3369 goto exit;
3370 Py_DECREF(list);
3371 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003374 }
3375 do {
3376 /* Skip over . and .. */
3377 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3378 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003379 v = PyUnicode_FromWideChar(wFileData.cFileName,
3380 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003381 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003382 Py_DECREF(list);
3383 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 break;
3385 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003387 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388 Py_DECREF(list);
3389 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003390 break;
3391 }
3392 Py_DECREF(v);
3393 }
3394 Py_BEGIN_ALLOW_THREADS
3395 result = FindNextFileW(hFindFile, &wFileData);
3396 Py_END_ALLOW_THREADS
3397 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3398 it got to the end of the directory. */
3399 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003400 Py_DECREF(list);
3401 list = win32_error_unicode("FindNextFileW", wnamebuf);
3402 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 }
3404 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003405
Larry Hastings9cf065c2012-06-22 16:30:09 -07003406 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003407 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408 strcpy(namebuf, path.narrow);
3409 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003410 if (len > 0) {
3411 char ch = namebuf[len-1];
3412 if (ch != SEP && ch != ALTSEP && ch != ':')
3413 namebuf[len++] = '/';
3414 strcpy(namebuf + len, "*.*");
3415 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003416
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003419
Antoine Pitroub73caab2010-08-09 23:39:31 +00003420 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003421 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003422 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 if (hFindFile == INVALID_HANDLE_VALUE) {
3424 int error = GetLastError();
3425 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 goto exit;
3427 Py_DECREF(list);
3428 list = win32_error("FindFirstFile", namebuf);
3429 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 }
3431 do {
3432 /* Skip over . and .. */
3433 if (strcmp(FileData.cFileName, ".") != 0 &&
3434 strcmp(FileData.cFileName, "..") != 0) {
3435 v = PyBytes_FromString(FileData.cFileName);
3436 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437 Py_DECREF(list);
3438 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 break;
3440 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 Py_DECREF(list);
3444 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 break;
3446 }
3447 Py_DECREF(v);
3448 }
3449 Py_BEGIN_ALLOW_THREADS
3450 result = FindNextFile(hFindFile, &FileData);
3451 Py_END_ALLOW_THREADS
3452 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3453 it got to the end of the directory. */
3454 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003455 Py_DECREF(list);
3456 list = win32_error("FindNextFile", namebuf);
3457 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 }
3459 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003460
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461exit:
3462 if (hFindFile != INVALID_HANDLE_VALUE) {
3463 if (FindClose(hFindFile) == FALSE) {
3464 if (list != NULL) {
3465 Py_DECREF(list);
3466 list = win32_error_object("FindClose", path.object);
3467 }
3468 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003469 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470 if (wnamebuf)
3471 free(wnamebuf);
3472 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003473
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003475
Tim Peters0bb44a42000-09-15 07:44:49 +00003476#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003478 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003480 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003482 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003483 if (*pt == ALTSEP)
3484 *pt = SEP;
3485 if (namebuf[len-1] != SEP)
3486 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003487 strcpy(namebuf + len, "*.*");
3488
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 if ((list = PyList_New(0)) == NULL) {
3490 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003491 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003492
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003493 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3494 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003495 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003496 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3497 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3498 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003499
3500 if (rc != NO_ERROR) {
3501 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 Py_DECREF(list);
3503 list = posix_error_with_filename(path.narrow);
3504 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003505 }
3506
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003507 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003508 do {
3509 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003510 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003511 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003512
3513 strcpy(namebuf, ep.achName);
3514
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003515 /* Leave Case of Name Alone -- In Native Form */
3516 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003517
Christian Heimes72b710a2008-05-26 13:28:38 +00003518 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003519 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_DECREF(list);
3521 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003522 break;
3523 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003524 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003525 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 Py_DECREF(list);
3527 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003528 break;
3529 }
3530 Py_DECREF(v);
3531 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3532 }
3533
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534exit:
3535 path_cleanup(&path);
3536
3537 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003538#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003539
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003541 /* v is never read, so it does not need to be initialized yet. */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003542 if (path.narrow && !PyArg_ParseTuple(args, "U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003543 arg_is_unicode = 0;
3544 PyErr_Clear();
3545 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546#ifdef HAVE_FDOPENDIR
3547 if (path.fd != -1) {
3548 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003549 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003551 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003552
3553 if (fd == -1) {
3554 list = posix_error();
3555 goto exit;
3556 }
3557
3558 Py_BEGIN_ALLOW_THREADS
3559 dirp = fdopendir(fd);
3560 Py_END_ALLOW_THREADS
3561 }
3562 else
3563#endif
3564 {
3565 char *name = path.narrow ? path.narrow : ".";
3566 Py_BEGIN_ALLOW_THREADS
3567 dirp = opendir(name);
3568 Py_END_ALLOW_THREADS
3569 }
3570
3571 if (dirp == NULL) {
3572 list = path_error("listdir", &path);
3573 goto exit;
3574 }
3575 if ((list = PyList_New(0)) == NULL) {
3576 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 }
3578 for (;;) {
3579 errno = 0;
3580 Py_BEGIN_ALLOW_THREADS
3581 ep = readdir(dirp);
3582 Py_END_ALLOW_THREADS
3583 if (ep == NULL) {
3584 if (errno == 0) {
3585 break;
3586 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 Py_DECREF(list);
3588 list = path_error("listdir", &path);
3589 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 }
3591 }
3592 if (ep->d_name[0] == '.' &&
3593 (NAMLEN(ep) == 1 ||
3594 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3595 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00003596 if (arg_is_unicode)
3597 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3598 else
3599 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 break;
3603 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003607 break;
3608 }
3609 Py_DECREF(v);
3610 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003611
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612exit:
3613 if (dirp != NULL) {
3614 Py_BEGIN_ALLOW_THREADS
3615 if (fd > -1)
3616 rewinddir(dirp);
3617 closedir(dirp);
3618 Py_END_ALLOW_THREADS
3619 }
3620
3621 path_cleanup(&path);
3622
3623 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003624
Tim Peters0bb44a42000-09-15 07:44:49 +00003625#endif /* which OS */
3626} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003627
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003628#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003629/* A helper function for abspath on win32 */
3630static PyObject *
3631posix__getfullpathname(PyObject *self, PyObject *args)
3632{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003633 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003634 char outbuf[MAX_PATH*2];
3635 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003636 PyObject *po;
3637
3638 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3639 {
3640 wchar_t *wpath;
3641 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3642 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 DWORD result;
3644 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003645
3646 wpath = PyUnicode_AsUnicode(po);
3647 if (wpath == NULL)
3648 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003650 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003652 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003653 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 if (!woutbufp)
3655 return PyErr_NoMemory();
3656 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3657 }
3658 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003659 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003661 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003662 if (woutbufp != woutbuf)
3663 free(woutbufp);
3664 return v;
3665 }
3666 /* Drop the argument parsing error as narrow strings
3667 are also valid. */
3668 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003669
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003670 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3671 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003673 if (win32_warn_bytes_api())
3674 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003675 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003676 outbuf, &temp)) {
3677 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003678 return NULL;
3679 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003680 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3681 return PyUnicode_Decode(outbuf, strlen(outbuf),
3682 Py_FileSystemDefaultEncoding, NULL);
3683 }
3684 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003685} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003686
Brian Curtind25aef52011-06-13 15:16:04 -05003687
Brian Curtinf5e76d02010-11-24 13:14:05 +00003688
Brian Curtind40e6f72010-07-08 21:39:08 +00003689/* A helper function for samepath on windows */
3690static PyObject *
3691posix__getfinalpathname(PyObject *self, PyObject *args)
3692{
3693 HANDLE hFile;
3694 int buf_size;
3695 wchar_t *target_path;
3696 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003697 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003698 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003699
Victor Stinnereb5657a2011-09-30 01:44:27 +02003700 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003701 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003702 path = PyUnicode_AsUnicode(po);
3703 if (path == NULL)
3704 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003705
3706 if(!check_GetFinalPathNameByHandle()) {
3707 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3708 NotImplementedError. */
3709 return PyErr_Format(PyExc_NotImplementedError,
3710 "GetFinalPathNameByHandle not available on this platform");
3711 }
3712
3713 hFile = CreateFileW(
3714 path,
3715 0, /* desired access */
3716 0, /* share mode */
3717 NULL, /* security attributes */
3718 OPEN_EXISTING,
3719 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3720 FILE_FLAG_BACKUP_SEMANTICS,
3721 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003722
Victor Stinnereb5657a2011-09-30 01:44:27 +02003723 if(hFile == INVALID_HANDLE_VALUE)
3724 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003725
3726 /* We have a good handle to the target, use it to determine the
3727 target path name. */
3728 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3729
3730 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003731 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003732
3733 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3734 if(!target_path)
3735 return PyErr_NoMemory();
3736
3737 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3738 buf_size, VOLUME_NAME_DOS);
3739 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003740 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003741
3742 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003743 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003744
3745 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003746 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003747 free(target_path);
3748 return result;
3749
3750} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003751
3752static PyObject *
3753posix__getfileinformation(PyObject *self, PyObject *args)
3754{
3755 HANDLE hFile;
3756 BY_HANDLE_FILE_INFORMATION info;
3757 int fd;
3758
3759 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3760 return NULL;
3761
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003762 if (!_PyVerify_fd(fd))
3763 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003764
3765 hFile = (HANDLE)_get_osfhandle(fd);
3766 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003767 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003768
3769 if (!GetFileInformationByHandle(hFile, &info))
3770 return win32_error("_getfileinformation", NULL);
3771
3772 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3773 info.nFileIndexHigh,
3774 info.nFileIndexLow);
3775}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003776
Brian Curtin95d028f2011-06-09 09:10:38 -05003777PyDoc_STRVAR(posix__isdir__doc__,
3778"Return true if the pathname refers to an existing directory.");
3779
Brian Curtin9c669cc2011-06-08 18:17:18 -05003780static PyObject *
3781posix__isdir(PyObject *self, PyObject *args)
3782{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003783 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003784 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003785 DWORD attributes;
3786
3787 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003788 wchar_t *wpath = PyUnicode_AsUnicode(po);
3789 if (wpath == NULL)
3790 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003791
3792 attributes = GetFileAttributesW(wpath);
3793 if (attributes == INVALID_FILE_ATTRIBUTES)
3794 Py_RETURN_FALSE;
3795 goto check;
3796 }
3797 /* Drop the argument parsing error as narrow strings
3798 are also valid. */
3799 PyErr_Clear();
3800
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003801 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003802 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003803 if (win32_warn_bytes_api())
3804 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003805 attributes = GetFileAttributesA(path);
3806 if (attributes == INVALID_FILE_ATTRIBUTES)
3807 Py_RETURN_FALSE;
3808
3809check:
3810 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3811 Py_RETURN_TRUE;
3812 else
3813 Py_RETURN_FALSE;
3814}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003815#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003817PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003818"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3819Create a directory.\n\
3820\n\
3821If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3822 and path should be relative; path will then be relative to that directory.\n\
3823dir_fd may not be implemented on your platform.\n\
3824 If it is unavailable, using it will raise a NotImplementedError.\n\
3825\n\
3826The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003827
Barry Warsaw53699e91996-12-10 23:23:01 +00003828static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003829posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003830{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003831 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003832 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003833 int dir_fd = DEFAULT_DIR_FD;
3834 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3835 PyObject *return_value = NULL;
3836 int result;
3837
3838 memset(&path, 0, sizeof(path));
3839 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3840 path_converter, &path, &mode,
3841#ifdef HAVE_MKDIRAT
3842 dir_fd_converter, &dir_fd
3843#else
3844 dir_fd_unavailable, &dir_fd
3845#endif
3846 ))
3847 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003848
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003849#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003850 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003851 if (path.wide)
3852 result = CreateDirectoryW(path.wide, NULL);
3853 else
3854 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003855 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003856
Larry Hastings9cf065c2012-06-22 16:30:09 -07003857 if (!result) {
3858 return_value = win32_error_object("mkdir", path.object);
3859 goto exit;
3860 }
3861#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003862 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003863#if HAVE_MKDIRAT
3864 if (dir_fd != DEFAULT_DIR_FD)
3865 result = mkdirat(dir_fd, path.narrow, mode);
3866 else
3867#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003868#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003869 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003870#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003871 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003872#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003874 if (result < 0) {
3875 return_value = path_error("mkdir", &path);
3876 goto exit;
3877 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003878#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879 return_value = Py_None;
3880 Py_INCREF(Py_None);
3881exit:
3882 path_cleanup(&path);
3883 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003884}
3885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003886
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003887/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3888#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003889#include <sys/resource.h>
3890#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003891
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003892
3893#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003894PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003895"nice(inc) -> new_priority\n\n\
3896Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003897
Barry Warsaw53699e91996-12-10 23:23:01 +00003898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003899posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003900{
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003902
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3904 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003905
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 /* There are two flavours of 'nice': one that returns the new
3907 priority (as required by almost all standards out there) and the
3908 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3909 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003910
Victor Stinner8c62be82010-05-06 00:08:46 +00003911 If we are of the nice family that returns the new priority, we
3912 need to clear errno before the call, and check if errno is filled
3913 before calling posix_error() on a returnvalue of -1, because the
3914 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003915
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 errno = 0;
3917 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003918#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003919 if (value == 0)
3920 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003921#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 if (value == -1 && errno != 0)
3923 /* either nice() or getpriority() returned an error */
3924 return posix_error();
3925 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003926}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003927#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003928
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003929
3930#ifdef HAVE_GETPRIORITY
3931PyDoc_STRVAR(posix_getpriority__doc__,
3932"getpriority(which, who) -> current_priority\n\n\
3933Get program scheduling priority.");
3934
3935static PyObject *
3936posix_getpriority(PyObject *self, PyObject *args)
3937{
3938 int which, who, retval;
3939
3940 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3941 return NULL;
3942 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003943 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003944 if (errno != 0)
3945 return posix_error();
3946 return PyLong_FromLong((long)retval);
3947}
3948#endif /* HAVE_GETPRIORITY */
3949
3950
3951#ifdef HAVE_SETPRIORITY
3952PyDoc_STRVAR(posix_setpriority__doc__,
3953"setpriority(which, who, prio) -> None\n\n\
3954Set program scheduling priority.");
3955
3956static PyObject *
3957posix_setpriority(PyObject *self, PyObject *args)
3958{
3959 int which, who, prio, retval;
3960
3961 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3962 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003963 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003964 if (retval == -1)
3965 return posix_error();
3966 Py_RETURN_NONE;
3967}
3968#endif /* HAVE_SETPRIORITY */
3969
3970
Barry Warsaw53699e91996-12-10 23:23:01 +00003971static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003972internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003973{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974 char *function_name = is_replace ? "replace" : "rename";
3975 path_t src;
3976 path_t dst;
3977 int src_dir_fd = DEFAULT_DIR_FD;
3978 int dst_dir_fd = DEFAULT_DIR_FD;
3979 int dir_fd_specified;
3980 PyObject *return_value = NULL;
3981 char format[24];
3982 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3983
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003984#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003985 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003986 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003987#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003988 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003989#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003990
3991 memset(&src, 0, sizeof(src));
3992 memset(&dst, 0, sizeof(dst));
3993 strcpy(format, "O&O&|$O&O&:");
3994 strcat(format, function_name);
3995 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3996 path_converter, &src,
3997 path_converter, &dst,
3998 dir_fd_converter, &src_dir_fd,
3999 dir_fd_converter, &dst_dir_fd))
4000 return NULL;
4001
4002 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4003 (dst_dir_fd != DEFAULT_DIR_FD);
4004#ifndef HAVE_RENAMEAT
4005 if (dir_fd_specified) {
4006 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4007 goto exit;
4008 }
4009#endif
4010
4011 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4012 PyErr_Format(PyExc_ValueError,
4013 "%s: src and dst must be the same type", function_name);
4014 goto exit;
4015 }
4016
4017#ifdef MS_WINDOWS
4018 Py_BEGIN_ALLOW_THREADS
4019 if (src.wide)
4020 result = MoveFileExW(src.wide, dst.wide, flags);
4021 else
4022 result = MoveFileExA(src.narrow, dst.narrow, flags);
4023 Py_END_ALLOW_THREADS
4024
4025 if (!result) {
4026 return_value = win32_error_object(function_name, dst.object);
4027 goto exit;
4028 }
4029
4030#else
4031 Py_BEGIN_ALLOW_THREADS
4032#ifdef HAVE_RENAMEAT
4033 if (dir_fd_specified)
4034 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4035 else
4036#endif
4037 result = rename(src.narrow, dst.narrow);
4038 Py_END_ALLOW_THREADS
4039
4040 if (result) {
4041 return_value = path_error(function_name, &dst);
4042 goto exit;
4043 }
4044#endif
4045
4046 Py_INCREF(Py_None);
4047 return_value = Py_None;
4048exit:
4049 path_cleanup(&src);
4050 path_cleanup(&dst);
4051 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004052}
4053
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004054PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004055"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4056Rename a file or directory.\n\
4057\n\
4058If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4059 descriptor open to a directory, and the respective path string (src or dst)\n\
4060 should be relative; the path will then be relative to that directory.\n\
4061src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4062 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004063
4064static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004065posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004066{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004067 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004068}
4069
4070PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004071"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4072Rename a file or directory, overwriting the destination.\n\
4073\n\
4074If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4075 descriptor open to a directory, and the respective path string (src or dst)\n\
4076 should be relative; the path will then be relative to that directory.\n\
4077src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4078 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004079
4080static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004081posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004082{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004083 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004084}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004085
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004086PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004087"rmdir(path, *, dir_fd=None)\n\n\
4088Remove a directory.\n\
4089\n\
4090If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4091 and path should be relative; path will then be relative to that directory.\n\
4092dir_fd may not be implemented on your platform.\n\
4093 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004094
Barry Warsaw53699e91996-12-10 23:23:01 +00004095static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004096posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004097{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004098 path_t path;
4099 int dir_fd = DEFAULT_DIR_FD;
4100 static char *keywords[] = {"path", "dir_fd", NULL};
4101 int result;
4102 PyObject *return_value = NULL;
4103
4104 memset(&path, 0, sizeof(path));
4105 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4106 path_converter, &path,
4107#ifdef HAVE_UNLINKAT
4108 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004109#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004110 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004111#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004112 ))
4113 return NULL;
4114
4115 Py_BEGIN_ALLOW_THREADS
4116#ifdef MS_WINDOWS
4117 if (path.wide)
4118 result = RemoveDirectoryW(path.wide);
4119 else
4120 result = RemoveDirectoryA(path.narrow);
4121 result = !result; /* Windows, success=1, UNIX, success=0 */
4122#else
4123#ifdef HAVE_UNLINKAT
4124 if (dir_fd != DEFAULT_DIR_FD)
4125 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4126 else
4127#endif
4128 result = rmdir(path.narrow);
4129#endif
4130 Py_END_ALLOW_THREADS
4131
4132 if (result) {
4133 return_value = path_error("rmdir", &path);
4134 goto exit;
4135 }
4136
4137 return_value = Py_None;
4138 Py_INCREF(Py_None);
4139
4140exit:
4141 path_cleanup(&path);
4142 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004143}
4144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004145
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004146#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004147PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004148"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004149Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004150
Barry Warsaw53699e91996-12-10 23:23:01 +00004151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004152posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004153{
Victor Stinner8c62be82010-05-06 00:08:46 +00004154 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004155#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 wchar_t *command;
4157 if (!PyArg_ParseTuple(args, "u:system", &command))
4158 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004159
Victor Stinner8c62be82010-05-06 00:08:46 +00004160 Py_BEGIN_ALLOW_THREADS
4161 sts = _wsystem(command);
4162 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004163#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 PyObject *command_obj;
4165 char *command;
4166 if (!PyArg_ParseTuple(args, "O&:system",
4167 PyUnicode_FSConverter, &command_obj))
4168 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004169
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 command = PyBytes_AsString(command_obj);
4171 Py_BEGIN_ALLOW_THREADS
4172 sts = system(command);
4173 Py_END_ALLOW_THREADS
4174 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004175#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004176 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004177}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004178#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004179
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004181PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004182"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004183Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004184
Barry Warsaw53699e91996-12-10 23:23:01 +00004185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004186posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004187{
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 int i;
4189 if (!PyArg_ParseTuple(args, "i:umask", &i))
4190 return NULL;
4191 i = (int)umask(i);
4192 if (i < 0)
4193 return posix_error();
4194 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004195}
4196
Brian Curtind40e6f72010-07-08 21:39:08 +00004197#ifdef MS_WINDOWS
4198
4199/* override the default DeleteFileW behavior so that directory
4200symlinks can be removed with this function, the same as with
4201Unix symlinks */
4202BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4203{
4204 WIN32_FILE_ATTRIBUTE_DATA info;
4205 WIN32_FIND_DATAW find_data;
4206 HANDLE find_data_handle;
4207 int is_directory = 0;
4208 int is_link = 0;
4209
4210 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4211 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004212
Brian Curtind40e6f72010-07-08 21:39:08 +00004213 /* Get WIN32_FIND_DATA structure for the path to determine if
4214 it is a symlink */
4215 if(is_directory &&
4216 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4217 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4218
4219 if(find_data_handle != INVALID_HANDLE_VALUE) {
4220 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4221 FindClose(find_data_handle);
4222 }
4223 }
4224 }
4225
4226 if (is_directory && is_link)
4227 return RemoveDirectoryW(lpFileName);
4228
4229 return DeleteFileW(lpFileName);
4230}
4231#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004232
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004233PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004234"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004235Remove a file (same as remove()).\n\
4236\n\
4237If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4238 and path should be relative; path will then be relative to that directory.\n\
4239dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004240 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004241
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004242PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004243"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004244Remove a file (same as unlink()).\n\
4245\n\
4246If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4247 and path should be relative; path will then be relative to that directory.\n\
4248dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004249 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004250
Barry Warsaw53699e91996-12-10 23:23:01 +00004251static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004252posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004253{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004254 path_t path;
4255 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004256 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004257 int result;
4258 PyObject *return_value = NULL;
4259
4260 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004261 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004262 path_converter, &path,
4263#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004264 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004265#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004266 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004267#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004268 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004269 return NULL;
4270
4271 Py_BEGIN_ALLOW_THREADS
4272#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004273 if (path.wide)
4274 result = Py_DeleteFileW(path.wide);
4275 else
4276 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004277 result = !result; /* Windows, success=1, UNIX, success=0 */
4278#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004279#ifdef HAVE_UNLINKAT
4280 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004281 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004282 else
4283#endif /* HAVE_UNLINKAT */
4284 result = unlink(path.narrow);
4285#endif
4286 Py_END_ALLOW_THREADS
4287
4288 if (result) {
4289 return_value = path_error("unlink", &path);
4290 goto exit;
4291 }
4292
4293 return_value = Py_None;
4294 Py_INCREF(Py_None);
4295
4296exit:
4297 path_cleanup(&path);
4298 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004299}
4300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004301
Guido van Rossumb6775db1994-08-01 11:34:53 +00004302#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004303PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004304"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004305Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004306
Barry Warsaw53699e91996-12-10 23:23:01 +00004307static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004308posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004309{
Victor Stinner8c62be82010-05-06 00:08:46 +00004310 struct utsname u;
4311 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00004312
Victor Stinner8c62be82010-05-06 00:08:46 +00004313 Py_BEGIN_ALLOW_THREADS
4314 res = uname(&u);
4315 Py_END_ALLOW_THREADS
4316 if (res < 0)
4317 return posix_error();
4318 return Py_BuildValue("(sssss)",
4319 u.sysname,
4320 u.nodename,
4321 u.release,
4322 u.version,
4323 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004324}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004325#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004326
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004327
Larry Hastings9cf065c2012-06-22 16:30:09 -07004328PyDoc_STRVAR(posix_utime__doc__,
4329"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4330Set the access and modified time of path.\n\
4331\n\
4332path may always be specified as a string.\n\
4333On some platforms, path may also be specified as an open file descriptor.\n\
4334 If this functionality is unavailable, using it raises an exception.\n\
4335\n\
4336If times is not None, it must be a tuple (atime, mtime);\n\
4337 atime and mtime should be expressed as float seconds since the epoch.\n\
4338If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4339 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4340 since the epoch.\n\
4341If both times and ns are None, utime uses the current time.\n\
4342Specifying tuples for both times and ns is an error.\n\
4343\n\
4344If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4345 and path should be relative; path will then be relative to that directory.\n\
4346If follow_symlinks is False, and the last element of the path is a symbolic\n\
4347 link, utime will modify the symbolic link itself instead of the file the\n\
4348 link points to.\n\
4349It is an error to use dir_fd or follow_symlinks when specifying path\n\
4350 as an open file descriptor.\n\
4351dir_fd and follow_symlinks may not be available on your platform.\n\
4352 If they are unavailable, using them will raise a NotImplementedError.");
4353
4354typedef struct {
4355 int now;
4356 time_t atime_s;
4357 long atime_ns;
4358 time_t mtime_s;
4359 long mtime_ns;
4360} utime_t;
4361
4362/*
4363 * these macros assume that "utime" is a pointer to a utime_t
4364 * they also intentionally leak the declaration of a pointer named "time"
4365 */
4366#define UTIME_TO_TIMESPEC \
4367 struct timespec ts[2]; \
4368 struct timespec *time; \
4369 if (utime->now) \
4370 time = NULL; \
4371 else { \
4372 ts[0].tv_sec = utime->atime_s; \
4373 ts[0].tv_nsec = utime->atime_ns; \
4374 ts[1].tv_sec = utime->mtime_s; \
4375 ts[1].tv_nsec = utime->mtime_ns; \
4376 time = ts; \
4377 } \
4378
4379#define UTIME_TO_TIMEVAL \
4380 struct timeval tv[2]; \
4381 struct timeval *time; \
4382 if (utime->now) \
4383 time = NULL; \
4384 else { \
4385 tv[0].tv_sec = utime->atime_s; \
4386 tv[0].tv_usec = utime->atime_ns / 1000; \
4387 tv[1].tv_sec = utime->mtime_s; \
4388 tv[1].tv_usec = utime->mtime_ns / 1000; \
4389 time = tv; \
4390 } \
4391
4392#define UTIME_TO_UTIMBUF \
4393 struct utimbuf u[2]; \
4394 struct utimbuf *time; \
4395 if (utime->now) \
4396 time = NULL; \
4397 else { \
4398 u.actime = utime->atime_s; \
4399 u.modtime = utime->mtime_s; \
4400 time = u; \
4401 }
4402
4403#define UTIME_TO_TIME_T \
4404 time_t timet[2]; \
4405 struct timet time; \
4406 if (utime->now) \
4407 time = NULL; \
4408 else { \
4409 timet[0] = utime->atime_s; \
4410 timet[1] = utime->mtime_s; \
4411 time = &timet; \
4412 } \
4413
4414
4415#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4416
4417#if UTIME_HAVE_DIR_FD
4418
4419static int
4420utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4421{
4422#ifdef HAVE_UTIMENSAT
4423 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4424 UTIME_TO_TIMESPEC;
4425 return utimensat(dir_fd, path, time, flags);
4426#elif defined(HAVE_FUTIMESAT)
4427 UTIME_TO_TIMEVAL;
4428 /*
4429 * follow_symlinks will never be false here;
4430 * we only allow !follow_symlinks and dir_fd together
4431 * if we have utimensat()
4432 */
4433 assert(follow_symlinks);
4434 return futimesat(dir_fd, path, time);
4435#endif
4436}
4437
4438#endif
4439
4440#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4441
4442#if UTIME_HAVE_FD
4443
4444static int
4445utime_fd(utime_t *utime, int fd)
4446{
4447#ifdef HAVE_FUTIMENS
4448 UTIME_TO_TIMESPEC;
4449 return futimens(fd, time);
4450#else
4451 UTIME_TO_TIMEVAL;
4452 return futimes(fd, time);
4453#endif
4454}
4455
4456#endif
4457
4458
4459#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4460 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4461
4462#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4463
4464static int
4465utime_nofollow_symlinks(utime_t *utime, char *path)
4466{
4467#ifdef HAVE_UTIMENSAT
4468 UTIME_TO_TIMESPEC;
4469 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4470#else
4471 UTIME_TO_TIMEVAL;
4472 return lutimes(path, time);
4473#endif
4474}
4475
4476#endif
4477
4478#ifndef MS_WINDOWS
4479
4480static int
4481utime_default(utime_t *utime, char *path)
4482{
4483#ifdef HAVE_UTIMENSAT
4484 UTIME_TO_TIMESPEC;
4485 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4486#elif defined(HAVE_UTIMES)
4487 UTIME_TO_TIMEVAL;
4488 return utimes(path, time);
4489#elif defined(HAVE_UTIME_H)
4490 UTIME_TO_UTIMBUF;
4491 return utime(path, time);
4492#else
4493 UTIME_TO_TIME_T;
4494 return utime(path, time);
4495#endif
4496}
4497
4498#endif
4499
Larry Hastings76ad59b2012-05-03 00:30:07 -07004500static int
4501split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4502{
4503 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004504 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004505 divmod = PyNumber_Divmod(py_long, billion);
4506 if (!divmod)
4507 goto exit;
4508 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4509 if ((*s == -1) && PyErr_Occurred())
4510 goto exit;
4511 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004512 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004513 goto exit;
4514
4515 result = 1;
4516exit:
4517 Py_XDECREF(divmod);
4518 return result;
4519}
4520
Larry Hastings9cf065c2012-06-22 16:30:09 -07004521static PyObject *
4522posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004523{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004524 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004525 PyObject *times = NULL;
4526 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004527 int dir_fd = DEFAULT_DIR_FD;
4528 int follow_symlinks = 1;
4529 char *keywords[] = {"path", "times", "ns", "dir_fd",
4530 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004531
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004533
Larry Hastings9cf065c2012-06-22 16:30:09 -07004534#ifdef MS_WINDOWS
4535 HANDLE hFile;
4536 FILETIME atime, mtime;
4537#else
4538 int result;
4539#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004540
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004542
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543 memset(&path, 0, sizeof(path));
4544#if UTIME_HAVE_FD
4545 path.allow_fd = 1;
4546#endif
4547 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4548 "O&|O$OO&p:utime", keywords,
4549 path_converter, &path,
4550 &times, &ns,
4551#if UTIME_HAVE_DIR_FD
4552 dir_fd_converter, &dir_fd,
4553#else
4554 dir_fd_unavailable, &dir_fd,
4555#endif
4556 &follow_symlinks
4557 ))
4558 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004559
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560 if (times && (times != Py_None) && ns) {
4561 PyErr_SetString(PyExc_ValueError,
4562 "utime: you may specify either 'times'"
4563 " or 'ns' but not both");
4564 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004565 }
4566
4567 if (times && (times != Py_None)) {
4568 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004569 PyErr_SetString(PyExc_TypeError,
4570 "utime: 'times' must be either"
4571 " a tuple of two ints or None");
4572 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004573 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004575 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004576 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004577 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578 &utime.mtime_s, &utime.mtime_ns) == -1) {
4579 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004580 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004581 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004583 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584 PyErr_SetString(PyExc_TypeError,
4585 "utime: 'ns' must be a tuple of two ints");
4586 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004587 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004589 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004591 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592 &utime.mtime_s, &utime.mtime_ns)) {
4593 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004594 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595 }
4596 else {
4597 /* times and ns are both None/unspecified. use "now". */
4598 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004599 }
4600
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4602 if (follow_symlinks_specified("utime", follow_symlinks))
4603 goto exit;
4604#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004605
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4607 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4608 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4609 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004610
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611#if !defined(HAVE_UTIMENSAT)
4612 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
4613 PyErr_SetString(PyExc_RuntimeError,
4614 "utime: cannot use dir_fd and follow_symlinks "
4615 "together on this platform");
4616 goto exit;
4617 }
4618#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004619
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004620#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621 Py_BEGIN_ALLOW_THREADS
4622 if (path.wide)
4623 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004624 NULL, OPEN_EXISTING,
4625 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004626 else
4627 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004628 NULL, OPEN_EXISTING,
4629 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630 Py_END_ALLOW_THREADS
4631 if (hFile == INVALID_HANDLE_VALUE) {
4632 win32_error_object("utime", path.object);
4633 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004634 }
4635
Larry Hastings9cf065c2012-06-22 16:30:09 -07004636 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004637 SYSTEMTIME now;
4638 GetSystemTime(&now);
4639 if (!SystemTimeToFileTime(&now, &mtime) ||
4640 !SystemTimeToFileTime(&now, &atime)) {
4641 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004643 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004644 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004645 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4647 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004648 }
4649 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4650 /* Avoid putting the file name into the error here,
4651 as that may confuse the user into believing that
4652 something is wrong with the file, when it also
4653 could be the time stamp that gives a problem. */
4654 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004655 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004656 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004657#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004658 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004659
Larry Hastings9cf065c2012-06-22 16:30:09 -07004660#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4661 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4662 result = utime_nofollow_symlinks(&utime, path.narrow);
4663 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004664#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665
4666#if UTIME_HAVE_DIR_FD
4667 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4668 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4669 else
4670#endif
4671
4672#if UTIME_HAVE_FD
4673 if (path.fd != -1)
4674 result = utime_fd(&utime, path.fd);
4675 else
4676#endif
4677
4678 result = utime_default(&utime, path.narrow);
4679
4680 Py_END_ALLOW_THREADS
4681
4682 if (result < 0) {
4683 /* see previous comment about not putting filename in error here */
4684 return_value = posix_error();
4685 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004686 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004687
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004688#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004689
4690 Py_INCREF(Py_None);
4691 return_value = Py_None;
4692
4693exit:
4694 path_cleanup(&path);
4695#ifdef MS_WINDOWS
4696 if (hFile != INVALID_HANDLE_VALUE)
4697 CloseHandle(hFile);
4698#endif
4699 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004700}
4701
Guido van Rossum3b066191991-06-04 19:40:25 +00004702/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004703
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004704PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004705"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004706Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004707
Barry Warsaw53699e91996-12-10 23:23:01 +00004708static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004709posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004710{
Victor Stinner8c62be82010-05-06 00:08:46 +00004711 int sts;
4712 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4713 return NULL;
4714 _exit(sts);
4715 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004716}
4717
Martin v. Löwis114619e2002-10-07 06:44:21 +00004718#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4719static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004720free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004721{
Victor Stinner8c62be82010-05-06 00:08:46 +00004722 Py_ssize_t i;
4723 for (i = 0; i < count; i++)
4724 PyMem_Free(array[i]);
4725 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004726}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004727
Antoine Pitrou69f71142009-05-24 21:25:49 +00004728static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004729int fsconvert_strdup(PyObject *o, char**out)
4730{
Victor Stinner8c62be82010-05-06 00:08:46 +00004731 PyObject *bytes;
4732 Py_ssize_t size;
4733 if (!PyUnicode_FSConverter(o, &bytes))
4734 return 0;
4735 size = PyBytes_GET_SIZE(bytes);
4736 *out = PyMem_Malloc(size+1);
4737 if (!*out)
4738 return 0;
4739 memcpy(*out, PyBytes_AsString(bytes), size+1);
4740 Py_DECREF(bytes);
4741 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004742}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004743#endif
4744
Ross Lagerwall7807c352011-03-17 20:20:30 +02004745#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004746static char**
4747parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4748{
Victor Stinner8c62be82010-05-06 00:08:46 +00004749 char **envlist;
4750 Py_ssize_t i, pos, envc;
4751 PyObject *keys=NULL, *vals=NULL;
4752 PyObject *key, *val, *key2, *val2;
4753 char *p, *k, *v;
4754 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004755
Victor Stinner8c62be82010-05-06 00:08:46 +00004756 i = PyMapping_Size(env);
4757 if (i < 0)
4758 return NULL;
4759 envlist = PyMem_NEW(char *, i + 1);
4760 if (envlist == NULL) {
4761 PyErr_NoMemory();
4762 return NULL;
4763 }
4764 envc = 0;
4765 keys = PyMapping_Keys(env);
4766 vals = PyMapping_Values(env);
4767 if (!keys || !vals)
4768 goto error;
4769 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4770 PyErr_Format(PyExc_TypeError,
4771 "env.keys() or env.values() is not a list");
4772 goto error;
4773 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004774
Victor Stinner8c62be82010-05-06 00:08:46 +00004775 for (pos = 0; pos < i; pos++) {
4776 key = PyList_GetItem(keys, pos);
4777 val = PyList_GetItem(vals, pos);
4778 if (!key || !val)
4779 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004780
Victor Stinner8c62be82010-05-06 00:08:46 +00004781 if (PyUnicode_FSConverter(key, &key2) == 0)
4782 goto error;
4783 if (PyUnicode_FSConverter(val, &val2) == 0) {
4784 Py_DECREF(key2);
4785 goto error;
4786 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004787
4788#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004789 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4790 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004791#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004792 k = PyBytes_AsString(key2);
4793 v = PyBytes_AsString(val2);
4794 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004795
Victor Stinner8c62be82010-05-06 00:08:46 +00004796 p = PyMem_NEW(char, len);
4797 if (p == NULL) {
4798 PyErr_NoMemory();
4799 Py_DECREF(key2);
4800 Py_DECREF(val2);
4801 goto error;
4802 }
4803 PyOS_snprintf(p, len, "%s=%s", k, v);
4804 envlist[envc++] = p;
4805 Py_DECREF(key2);
4806 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004807#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004808 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004809#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004810 }
4811 Py_DECREF(vals);
4812 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004813
Victor Stinner8c62be82010-05-06 00:08:46 +00004814 envlist[envc] = 0;
4815 *envc_ptr = envc;
4816 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004817
4818error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004819 Py_XDECREF(keys);
4820 Py_XDECREF(vals);
4821 while (--envc >= 0)
4822 PyMem_DEL(envlist[envc]);
4823 PyMem_DEL(envlist);
4824 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004825}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004826
Ross Lagerwall7807c352011-03-17 20:20:30 +02004827static char**
4828parse_arglist(PyObject* argv, Py_ssize_t *argc)
4829{
4830 int i;
4831 char **argvlist = PyMem_NEW(char *, *argc+1);
4832 if (argvlist == NULL) {
4833 PyErr_NoMemory();
4834 return NULL;
4835 }
4836 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004837 PyObject* item = PySequence_ITEM(argv, i);
4838 if (item == NULL)
4839 goto fail;
4840 if (!fsconvert_strdup(item, &argvlist[i])) {
4841 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004842 goto fail;
4843 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004844 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004845 }
4846 argvlist[*argc] = NULL;
4847 return argvlist;
4848fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004849 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004850 free_string_array(argvlist, *argc);
4851 return NULL;
4852}
4853#endif
4854
4855#ifdef HAVE_EXECV
4856PyDoc_STRVAR(posix_execv__doc__,
4857"execv(path, args)\n\n\
4858Execute an executable path with arguments, replacing current process.\n\
4859\n\
4860 path: path of executable file\n\
4861 args: tuple or list of strings");
4862
4863static PyObject *
4864posix_execv(PyObject *self, PyObject *args)
4865{
4866 PyObject *opath;
4867 char *path;
4868 PyObject *argv;
4869 char **argvlist;
4870 Py_ssize_t argc;
4871
4872 /* execv has two arguments: (path, argv), where
4873 argv is a list or tuple of strings. */
4874
4875 if (!PyArg_ParseTuple(args, "O&O:execv",
4876 PyUnicode_FSConverter,
4877 &opath, &argv))
4878 return NULL;
4879 path = PyBytes_AsString(opath);
4880 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4881 PyErr_SetString(PyExc_TypeError,
4882 "execv() arg 2 must be a tuple or list");
4883 Py_DECREF(opath);
4884 return NULL;
4885 }
4886 argc = PySequence_Size(argv);
4887 if (argc < 1) {
4888 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4889 Py_DECREF(opath);
4890 return NULL;
4891 }
4892
4893 argvlist = parse_arglist(argv, &argc);
4894 if (argvlist == NULL) {
4895 Py_DECREF(opath);
4896 return NULL;
4897 }
4898
4899 execv(path, argvlist);
4900
4901 /* If we get here it's definitely an error */
4902
4903 free_string_array(argvlist, argc);
4904 Py_DECREF(opath);
4905 return posix_error();
4906}
4907
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004908PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004909"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004910Execute a path with arguments and environment, replacing current process.\n\
4911\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004912 path: path of executable file\n\
4913 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004914 env: dictionary of strings mapping to strings\n\
4915\n\
4916On some platforms, you may specify an open file descriptor for path;\n\
4917 execve will execute the program the file descriptor is open to.\n\
4918 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004919
Barry Warsaw53699e91996-12-10 23:23:01 +00004920static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004921posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004922{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004923 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004924 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004925 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004927 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004928 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004929
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 /* execve has three arguments: (path, argv, env), where
4931 argv is a list or tuple of strings and env is a dictionary
4932 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004933
Larry Hastings9cf065c2012-06-22 16:30:09 -07004934 memset(&path, 0, sizeof(path));
4935#ifdef HAVE_FEXECVE
4936 path.allow_fd = 1;
4937#endif
4938 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4939 path_converter, &path,
4940 &argv, &env
4941 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004943
Ross Lagerwall7807c352011-03-17 20:20:30 +02004944 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946 "execve: argv must be a tuple or list");
4947 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004949 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004950 if (!PyMapping_Check(env)) {
4951 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004952 "execve: environment must be a mapping object");
4953 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004954 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004955
Ross Lagerwall7807c352011-03-17 20:20:30 +02004956 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004957 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004960
Victor Stinner8c62be82010-05-06 00:08:46 +00004961 envlist = parse_envlist(env, &envc);
4962 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004963 goto fail;
4964
Larry Hastings9cf065c2012-06-22 16:30:09 -07004965#ifdef HAVE_FEXECVE
4966 if (path.fd > -1)
4967 fexecve(path.fd, argvlist, envlist);
4968 else
4969#endif
4970 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004971
4972 /* If we get here it's definitely an error */
4973
Larry Hastings9cf065c2012-06-22 16:30:09 -07004974 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004975
4976 while (--envc >= 0)
4977 PyMem_DEL(envlist[envc]);
4978 PyMem_DEL(envlist);
4979 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004980 if (argvlist)
4981 free_string_array(argvlist, argc);
4982 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004983 return NULL;
4984}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985#endif /* HAVE_EXECV */
4986
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004987
Guido van Rossuma1065681999-01-25 23:20:23 +00004988#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004989PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004990"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004991Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004992\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 mode: mode of process creation\n\
4994 path: path of executable file\n\
4995 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004996
4997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004998posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004999{
Victor Stinner8c62be82010-05-06 00:08:46 +00005000 PyObject *opath;
5001 char *path;
5002 PyObject *argv;
5003 char **argvlist;
5004 int mode, i;
5005 Py_ssize_t argc;
5006 Py_intptr_t spawnval;
5007 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005008
Victor Stinner8c62be82010-05-06 00:08:46 +00005009 /* spawnv has three arguments: (mode, path, argv), where
5010 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005011
Victor Stinner8c62be82010-05-06 00:08:46 +00005012 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5013 PyUnicode_FSConverter,
5014 &opath, &argv))
5015 return NULL;
5016 path = PyBytes_AsString(opath);
5017 if (PyList_Check(argv)) {
5018 argc = PyList_Size(argv);
5019 getitem = PyList_GetItem;
5020 }
5021 else if (PyTuple_Check(argv)) {
5022 argc = PyTuple_Size(argv);
5023 getitem = PyTuple_GetItem;
5024 }
5025 else {
5026 PyErr_SetString(PyExc_TypeError,
5027 "spawnv() arg 2 must be a tuple or list");
5028 Py_DECREF(opath);
5029 return NULL;
5030 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005031
Victor Stinner8c62be82010-05-06 00:08:46 +00005032 argvlist = PyMem_NEW(char *, argc+1);
5033 if (argvlist == NULL) {
5034 Py_DECREF(opath);
5035 return PyErr_NoMemory();
5036 }
5037 for (i = 0; i < argc; i++) {
5038 if (!fsconvert_strdup((*getitem)(argv, i),
5039 &argvlist[i])) {
5040 free_string_array(argvlist, i);
5041 PyErr_SetString(
5042 PyExc_TypeError,
5043 "spawnv() arg 2 must contain only strings");
5044 Py_DECREF(opath);
5045 return NULL;
5046 }
5047 }
5048 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005049
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005050#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 Py_BEGIN_ALLOW_THREADS
5052 spawnval = spawnv(mode, path, argvlist);
5053 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005054#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 if (mode == _OLD_P_OVERLAY)
5056 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005057
Victor Stinner8c62be82010-05-06 00:08:46 +00005058 Py_BEGIN_ALLOW_THREADS
5059 spawnval = _spawnv(mode, path, argvlist);
5060 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005061#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005062
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 free_string_array(argvlist, argc);
5064 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005065
Victor Stinner8c62be82010-05-06 00:08:46 +00005066 if (spawnval == -1)
5067 return posix_error();
5068 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005069#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005070 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005071#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005073#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005074}
5075
5076
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005077PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005078"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005079Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005080\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005081 mode: mode of process creation\n\
5082 path: path of executable file\n\
5083 args: tuple or list of arguments\n\
5084 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005085
5086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005087posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005088{
Victor Stinner8c62be82010-05-06 00:08:46 +00005089 PyObject *opath;
5090 char *path;
5091 PyObject *argv, *env;
5092 char **argvlist;
5093 char **envlist;
5094 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005095 int mode;
5096 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005097 Py_intptr_t spawnval;
5098 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5099 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005100
Victor Stinner8c62be82010-05-06 00:08:46 +00005101 /* spawnve has four arguments: (mode, path, argv, env), where
5102 argv is a list or tuple of strings and env is a dictionary
5103 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005104
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5106 PyUnicode_FSConverter,
5107 &opath, &argv, &env))
5108 return NULL;
5109 path = PyBytes_AsString(opath);
5110 if (PyList_Check(argv)) {
5111 argc = PyList_Size(argv);
5112 getitem = PyList_GetItem;
5113 }
5114 else if (PyTuple_Check(argv)) {
5115 argc = PyTuple_Size(argv);
5116 getitem = PyTuple_GetItem;
5117 }
5118 else {
5119 PyErr_SetString(PyExc_TypeError,
5120 "spawnve() arg 2 must be a tuple or list");
5121 goto fail_0;
5122 }
5123 if (!PyMapping_Check(env)) {
5124 PyErr_SetString(PyExc_TypeError,
5125 "spawnve() arg 3 must be a mapping object");
5126 goto fail_0;
5127 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005128
Victor Stinner8c62be82010-05-06 00:08:46 +00005129 argvlist = PyMem_NEW(char *, argc+1);
5130 if (argvlist == NULL) {
5131 PyErr_NoMemory();
5132 goto fail_0;
5133 }
5134 for (i = 0; i < argc; i++) {
5135 if (!fsconvert_strdup((*getitem)(argv, i),
5136 &argvlist[i]))
5137 {
5138 lastarg = i;
5139 goto fail_1;
5140 }
5141 }
5142 lastarg = argc;
5143 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005144
Victor Stinner8c62be82010-05-06 00:08:46 +00005145 envlist = parse_envlist(env, &envc);
5146 if (envlist == NULL)
5147 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005148
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005149#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005150 Py_BEGIN_ALLOW_THREADS
5151 spawnval = spawnve(mode, path, argvlist, envlist);
5152 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005153#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005154 if (mode == _OLD_P_OVERLAY)
5155 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005156
Victor Stinner8c62be82010-05-06 00:08:46 +00005157 Py_BEGIN_ALLOW_THREADS
5158 spawnval = _spawnve(mode, path, argvlist, envlist);
5159 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005160#endif
Tim Peters25059d32001-12-07 20:35:43 +00005161
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 if (spawnval == -1)
5163 (void) posix_error();
5164 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005165#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005167#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005169#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005170
Victor Stinner8c62be82010-05-06 00:08:46 +00005171 while (--envc >= 0)
5172 PyMem_DEL(envlist[envc]);
5173 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005174 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005176 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005177 Py_DECREF(opath);
5178 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005179}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005180
5181/* OS/2 supports spawnvp & spawnvpe natively */
5182#if defined(PYOS_OS2)
5183PyDoc_STRVAR(posix_spawnvp__doc__,
5184"spawnvp(mode, file, args)\n\n\
5185Execute the program 'file' in a new process, using the environment\n\
5186search path to find the file.\n\
5187\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 mode: mode of process creation\n\
5189 file: executable file name\n\
5190 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005191
5192static PyObject *
5193posix_spawnvp(PyObject *self, PyObject *args)
5194{
Victor Stinner8c62be82010-05-06 00:08:46 +00005195 PyObject *opath;
5196 char *path;
5197 PyObject *argv;
5198 char **argvlist;
5199 int mode, i, argc;
5200 Py_intptr_t spawnval;
5201 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005202
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 /* spawnvp has three arguments: (mode, path, argv), where
5204 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005205
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5207 PyUnicode_FSConverter,
5208 &opath, &argv))
5209 return NULL;
5210 path = PyBytes_AsString(opath);
5211 if (PyList_Check(argv)) {
5212 argc = PyList_Size(argv);
5213 getitem = PyList_GetItem;
5214 }
5215 else if (PyTuple_Check(argv)) {
5216 argc = PyTuple_Size(argv);
5217 getitem = PyTuple_GetItem;
5218 }
5219 else {
5220 PyErr_SetString(PyExc_TypeError,
5221 "spawnvp() arg 2 must be a tuple or list");
5222 Py_DECREF(opath);
5223 return NULL;
5224 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005225
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 argvlist = PyMem_NEW(char *, argc+1);
5227 if (argvlist == NULL) {
5228 Py_DECREF(opath);
5229 return PyErr_NoMemory();
5230 }
5231 for (i = 0; i < argc; i++) {
5232 if (!fsconvert_strdup((*getitem)(argv, i),
5233 &argvlist[i])) {
5234 free_string_array(argvlist, i);
5235 PyErr_SetString(
5236 PyExc_TypeError,
5237 "spawnvp() arg 2 must contain only strings");
5238 Py_DECREF(opath);
5239 return NULL;
5240 }
5241 }
5242 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005243
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005245#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005246 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005247#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005249#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005250 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005251
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 free_string_array(argvlist, argc);
5253 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005254
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 if (spawnval == -1)
5256 return posix_error();
5257 else
5258 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005259}
5260
5261
5262PyDoc_STRVAR(posix_spawnvpe__doc__,
5263"spawnvpe(mode, file, args, env)\n\n\
5264Execute the program 'file' in a new process, using the environment\n\
5265search path to find the file.\n\
5266\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 mode: mode of process creation\n\
5268 file: executable file name\n\
5269 args: tuple or list of arguments\n\
5270 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005271
5272static PyObject *
5273posix_spawnvpe(PyObject *self, PyObject *args)
5274{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005275 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 char *path;
5277 PyObject *argv, *env;
5278 char **argvlist;
5279 char **envlist;
5280 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005281 int mode;
5282 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 Py_intptr_t spawnval;
5284 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5285 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005286
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 /* spawnvpe has four arguments: (mode, path, argv, env), where
5288 argv is a list or tuple of strings and env is a dictionary
5289 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005290
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5292 PyUnicode_FSConverter,
5293 &opath, &argv, &env))
5294 return NULL;
5295 path = PyBytes_AsString(opath);
5296 if (PyList_Check(argv)) {
5297 argc = PyList_Size(argv);
5298 getitem = PyList_GetItem;
5299 }
5300 else if (PyTuple_Check(argv)) {
5301 argc = PyTuple_Size(argv);
5302 getitem = PyTuple_GetItem;
5303 }
5304 else {
5305 PyErr_SetString(PyExc_TypeError,
5306 "spawnvpe() arg 2 must be a tuple or list");
5307 goto fail_0;
5308 }
5309 if (!PyMapping_Check(env)) {
5310 PyErr_SetString(PyExc_TypeError,
5311 "spawnvpe() arg 3 must be a mapping object");
5312 goto fail_0;
5313 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005314
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 argvlist = PyMem_NEW(char *, argc+1);
5316 if (argvlist == NULL) {
5317 PyErr_NoMemory();
5318 goto fail_0;
5319 }
5320 for (i = 0; i < argc; i++) {
5321 if (!fsconvert_strdup((*getitem)(argv, i),
5322 &argvlist[i]))
5323 {
5324 lastarg = i;
5325 goto fail_1;
5326 }
5327 }
5328 lastarg = argc;
5329 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005330
Victor Stinner8c62be82010-05-06 00:08:46 +00005331 envlist = parse_envlist(env, &envc);
5332 if (envlist == NULL)
5333 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005334
Victor Stinner8c62be82010-05-06 00:08:46 +00005335 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005336#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005337 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005338#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005339 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005340#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005341 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005342
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 if (spawnval == -1)
5344 (void) posix_error();
5345 else
5346 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005347
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 while (--envc >= 0)
5349 PyMem_DEL(envlist[envc]);
5350 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005351 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005352 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005353 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005354 Py_DECREF(opath);
5355 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005356}
5357#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005358#endif /* HAVE_SPAWNV */
5359
5360
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005361#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005362PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005363"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005364Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5365\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005366Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005367
5368static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005369posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005370{
Victor Stinner8c62be82010-05-06 00:08:46 +00005371 pid_t pid;
5372 int result = 0;
5373 _PyImport_AcquireLock();
5374 pid = fork1();
5375 if (pid == 0) {
5376 /* child: this clobbers and resets the import lock. */
5377 PyOS_AfterFork();
5378 } else {
5379 /* parent: release the import lock. */
5380 result = _PyImport_ReleaseLock();
5381 }
5382 if (pid == -1)
5383 return posix_error();
5384 if (result < 0) {
5385 /* Don't clobber the OSError if the fork failed. */
5386 PyErr_SetString(PyExc_RuntimeError,
5387 "not holding the import lock");
5388 return NULL;
5389 }
5390 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005391}
5392#endif
5393
5394
Guido van Rossumad0ee831995-03-01 10:34:45 +00005395#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005396PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005397"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005398Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005399Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005400
Barry Warsaw53699e91996-12-10 23:23:01 +00005401static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005402posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005403{
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 pid_t pid;
5405 int result = 0;
5406 _PyImport_AcquireLock();
5407 pid = fork();
5408 if (pid == 0) {
5409 /* child: this clobbers and resets the import lock. */
5410 PyOS_AfterFork();
5411 } else {
5412 /* parent: release the import lock. */
5413 result = _PyImport_ReleaseLock();
5414 }
5415 if (pid == -1)
5416 return posix_error();
5417 if (result < 0) {
5418 /* Don't clobber the OSError if the fork failed. */
5419 PyErr_SetString(PyExc_RuntimeError,
5420 "not holding the import lock");
5421 return NULL;
5422 }
5423 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005424}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005425#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005426
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005427#ifdef HAVE_SCHED_H
5428
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005429#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5430
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005431PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5432"sched_get_priority_max(policy)\n\n\
5433Get the maximum scheduling priority for *policy*.");
5434
5435static PyObject *
5436posix_sched_get_priority_max(PyObject *self, PyObject *args)
5437{
5438 int policy, max;
5439
5440 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5441 return NULL;
5442 max = sched_get_priority_max(policy);
5443 if (max < 0)
5444 return posix_error();
5445 return PyLong_FromLong(max);
5446}
5447
5448PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5449"sched_get_priority_min(policy)\n\n\
5450Get the minimum scheduling priority for *policy*.");
5451
5452static PyObject *
5453posix_sched_get_priority_min(PyObject *self, PyObject *args)
5454{
5455 int policy, min;
5456
5457 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5458 return NULL;
5459 min = sched_get_priority_min(policy);
5460 if (min < 0)
5461 return posix_error();
5462 return PyLong_FromLong(min);
5463}
5464
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005465#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5466
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005467#ifdef HAVE_SCHED_SETSCHEDULER
5468
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005469PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5470"sched_getscheduler(pid)\n\n\
5471Get the scheduling policy for the process with a PID of *pid*.\n\
5472Passing a PID of 0 returns the scheduling policy for the calling process.");
5473
5474static PyObject *
5475posix_sched_getscheduler(PyObject *self, PyObject *args)
5476{
5477 pid_t pid;
5478 int policy;
5479
5480 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5481 return NULL;
5482 policy = sched_getscheduler(pid);
5483 if (policy < 0)
5484 return posix_error();
5485 return PyLong_FromLong(policy);
5486}
5487
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005488#endif
5489
5490#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5491
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005492static PyObject *
5493sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5494{
5495 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005496 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005497
5498 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5499 return NULL;
5500 res = PyStructSequence_New(type);
5501 if (!res)
5502 return NULL;
5503 Py_INCREF(priority);
5504 PyStructSequence_SET_ITEM(res, 0, priority);
5505 return res;
5506}
5507
5508PyDoc_STRVAR(sched_param__doc__,
5509"sched_param(sched_priority): A scheduling parameter.\n\n\
5510Current has only one field: sched_priority");
5511
5512static PyStructSequence_Field sched_param_fields[] = {
5513 {"sched_priority", "the scheduling priority"},
5514 {0}
5515};
5516
5517static PyStructSequence_Desc sched_param_desc = {
5518 "sched_param", /* name */
5519 sched_param__doc__, /* doc */
5520 sched_param_fields,
5521 1
5522};
5523
5524static int
5525convert_sched_param(PyObject *param, struct sched_param *res)
5526{
5527 long priority;
5528
5529 if (Py_TYPE(param) != &SchedParamType) {
5530 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5531 return 0;
5532 }
5533 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5534 if (priority == -1 && PyErr_Occurred())
5535 return 0;
5536 if (priority > INT_MAX || priority < INT_MIN) {
5537 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5538 return 0;
5539 }
5540 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5541 return 1;
5542}
5543
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005544#endif
5545
5546#ifdef HAVE_SCHED_SETSCHEDULER
5547
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005548PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5549"sched_setscheduler(pid, policy, param)\n\n\
5550Set the scheduling policy, *policy*, for *pid*.\n\
5551If *pid* is 0, the calling process is changed.\n\
5552*param* is an instance of sched_param.");
5553
5554static PyObject *
5555posix_sched_setscheduler(PyObject *self, PyObject *args)
5556{
5557 pid_t pid;
5558 int policy;
5559 struct sched_param param;
5560
5561 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5562 &pid, &policy, &convert_sched_param, &param))
5563 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005564
5565 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005566 ** sched_setscheduler() returns 0 in Linux, but the previous
5567 ** scheduling policy under Solaris/Illumos, and others.
5568 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005569 */
5570 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005571 return posix_error();
5572 Py_RETURN_NONE;
5573}
5574
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005575#endif
5576
5577#ifdef HAVE_SCHED_SETPARAM
5578
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005579PyDoc_STRVAR(posix_sched_getparam__doc__,
5580"sched_getparam(pid) -> sched_param\n\n\
5581Returns scheduling parameters for the process with *pid* as an instance of the\n\
5582sched_param class. A PID of 0 means the calling process.");
5583
5584static PyObject *
5585posix_sched_getparam(PyObject *self, PyObject *args)
5586{
5587 pid_t pid;
5588 struct sched_param param;
5589 PyObject *res, *priority;
5590
5591 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5592 return NULL;
5593 if (sched_getparam(pid, &param))
5594 return posix_error();
5595 res = PyStructSequence_New(&SchedParamType);
5596 if (!res)
5597 return NULL;
5598 priority = PyLong_FromLong(param.sched_priority);
5599 if (!priority) {
5600 Py_DECREF(res);
5601 return NULL;
5602 }
5603 PyStructSequence_SET_ITEM(res, 0, priority);
5604 return res;
5605}
5606
5607PyDoc_STRVAR(posix_sched_setparam__doc__,
5608"sched_setparam(pid, param)\n\n\
5609Set scheduling parameters for a process with PID *pid*.\n\
5610A PID of 0 means the calling process.");
5611
5612static PyObject *
5613posix_sched_setparam(PyObject *self, PyObject *args)
5614{
5615 pid_t pid;
5616 struct sched_param param;
5617
5618 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5619 &pid, &convert_sched_param, &param))
5620 return NULL;
5621 if (sched_setparam(pid, &param))
5622 return posix_error();
5623 Py_RETURN_NONE;
5624}
5625
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005626#endif
5627
5628#ifdef HAVE_SCHED_RR_GET_INTERVAL
5629
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005630PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5631"sched_rr_get_interval(pid) -> float\n\n\
5632Return the round-robin quantum for the process with PID *pid* in seconds.");
5633
5634static PyObject *
5635posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5636{
5637 pid_t pid;
5638 struct timespec interval;
5639
5640 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5641 return NULL;
5642 if (sched_rr_get_interval(pid, &interval))
5643 return posix_error();
5644 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5645}
5646
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005647#endif
5648
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005649PyDoc_STRVAR(posix_sched_yield__doc__,
5650"sched_yield()\n\n\
5651Voluntarily relinquish the CPU.");
5652
5653static PyObject *
5654posix_sched_yield(PyObject *self, PyObject *noargs)
5655{
5656 if (sched_yield())
5657 return posix_error();
5658 Py_RETURN_NONE;
5659}
5660
Benjamin Peterson2740af82011-08-02 17:41:34 -05005661#ifdef HAVE_SCHED_SETAFFINITY
5662
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005663typedef struct {
5664 PyObject_HEAD;
5665 Py_ssize_t size;
5666 int ncpus;
5667 cpu_set_t *set;
5668} Py_cpu_set;
5669
5670static PyTypeObject cpu_set_type;
5671
5672static void
5673cpu_set_dealloc(Py_cpu_set *set)
5674{
5675 assert(set->set);
5676 CPU_FREE(set->set);
5677 Py_TYPE(set)->tp_free(set);
5678}
5679
5680static Py_cpu_set *
5681make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
5682{
5683 Py_cpu_set *set;
5684
5685 if (size < 0) {
5686 PyErr_SetString(PyExc_ValueError, "negative size");
5687 return NULL;
5688 }
5689 set = (Py_cpu_set *)type->tp_alloc(type, 0);
5690 if (!set)
5691 return NULL;
5692 set->ncpus = size;
5693 set->size = CPU_ALLOC_SIZE(size);
5694 set->set = CPU_ALLOC(size);
5695 if (!set->set) {
5696 type->tp_free(set);
5697 PyErr_NoMemory();
5698 return NULL;
5699 }
5700 CPU_ZERO_S(set->size, set->set);
5701 return set;
5702}
5703
5704static PyObject *
5705cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5706{
5707 int size;
5708
5709 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
5710 !PyArg_ParseTuple(args, "i:cpu_set", &size))
5711 return NULL;
5712 return (PyObject *)make_new_cpu_set(type, size);
5713}
5714
5715static PyObject *
5716cpu_set_repr(Py_cpu_set *set)
5717{
5718 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02005719}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005720
5721static Py_ssize_t
5722cpu_set_len(Py_cpu_set *set)
5723{
5724 return set->ncpus;
5725}
5726
5727static int
5728_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
5729{
5730 int cpu;
5731 if (!PyArg_ParseTuple(args, requester, &cpu))
5732 return -1;
5733 if (cpu < 0) {
5734 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
5735 return -1;
5736 }
5737 if (cpu >= set->ncpus) {
5738 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
5739 return -1;
5740 }
5741 return cpu;
5742}
5743
5744PyDoc_STRVAR(cpu_set_set_doc,
5745"cpu_set.set(i)\n\n\
5746Add CPU *i* to the set.");
5747
5748static PyObject *
5749cpu_set_set(Py_cpu_set *set, PyObject *args)
5750{
5751 int cpu = _get_cpu(set, "i|set", args);
5752 if (cpu == -1)
5753 return NULL;
5754 CPU_SET_S(cpu, set->size, set->set);
5755 Py_RETURN_NONE;
5756}
5757
5758PyDoc_STRVAR(cpu_set_count_doc,
5759"cpu_set.count() -> int\n\n\
5760Return the number of CPUs active in the set.");
5761
5762static PyObject *
5763cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5764{
5765 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5766}
5767
5768PyDoc_STRVAR(cpu_set_clear_doc,
5769"cpu_set.clear(i)\n\n\
5770Remove CPU *i* from the set.");
5771
5772static PyObject *
5773cpu_set_clear(Py_cpu_set *set, PyObject *args)
5774{
5775 int cpu = _get_cpu(set, "i|clear", args);
5776 if (cpu == -1)
5777 return NULL;
5778 CPU_CLR_S(cpu, set->size, set->set);
5779 Py_RETURN_NONE;
5780}
5781
5782PyDoc_STRVAR(cpu_set_isset_doc,
5783"cpu_set.isset(i) -> bool\n\n\
5784Test if CPU *i* is in the set.");
5785
5786static PyObject *
5787cpu_set_isset(Py_cpu_set *set, PyObject *args)
5788{
5789 int cpu = _get_cpu(set, "i|isset", args);
5790 if (cpu == -1)
5791 return NULL;
5792 if (CPU_ISSET_S(cpu, set->size, set->set))
5793 Py_RETURN_TRUE;
5794 Py_RETURN_FALSE;
5795}
5796
5797PyDoc_STRVAR(cpu_set_zero_doc,
5798"cpu_set.zero()\n\n\
5799Clear the cpu_set.");
5800
5801static PyObject *
5802cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5803{
5804 CPU_ZERO_S(set->size, set->set);
5805 Py_RETURN_NONE;
5806}
5807
5808static PyObject *
5809cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5810{
5811 int eq;
5812
Brian Curtindfc80e32011-08-10 20:28:54 -05005813 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5814 Py_RETURN_NOTIMPLEMENTED;
5815
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005816 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5817 if ((op == Py_EQ) ? eq : !eq)
5818 Py_RETURN_TRUE;
5819 else
5820 Py_RETURN_FALSE;
5821}
5822
5823#define CPU_SET_BINOP(name, op) \
5824 static PyObject * \
5825 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5826 if (res) { \
5827 Py_INCREF(res); \
5828 } \
5829 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005830 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005831 if (!res) \
5832 return NULL; \
5833 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005834 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005835 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005836 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005837 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005838 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005839 op(res->size, res->set, left->set, right->set); \
5840 return (PyObject *)res; \
5841 } \
5842 static PyObject * \
5843 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5844 return do_cpu_set_##name(left, right, NULL); \
5845 } \
5846 static PyObject * \
5847 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5848 return do_cpu_set_##name(left, right, left); \
5849 } \
5850
5851CPU_SET_BINOP(and, CPU_AND_S)
5852CPU_SET_BINOP(or, CPU_OR_S)
5853CPU_SET_BINOP(xor, CPU_XOR_S)
5854#undef CPU_SET_BINOP
5855
5856PyDoc_STRVAR(cpu_set_doc,
5857"cpu_set(size)\n\n\
5858Create an empty mask of CPUs.");
5859
5860static PyNumberMethods cpu_set_as_number = {
5861 0, /*nb_add*/
5862 0, /*nb_subtract*/
5863 0, /*nb_multiply*/
5864 0, /*nb_remainder*/
5865 0, /*nb_divmod*/
5866 0, /*nb_power*/
5867 0, /*nb_negative*/
5868 0, /*nb_positive*/
5869 0, /*nb_absolute*/
5870 0, /*nb_bool*/
5871 0, /*nb_invert*/
5872 0, /*nb_lshift*/
5873 0, /*nb_rshift*/
5874 (binaryfunc)cpu_set_and, /*nb_and*/
5875 (binaryfunc)cpu_set_xor, /*nb_xor*/
5876 (binaryfunc)cpu_set_or, /*nb_or*/
5877 0, /*nb_int*/
5878 0, /*nb_reserved*/
5879 0, /*nb_float*/
5880 0, /*nb_inplace_add*/
5881 0, /*nb_inplace_subtract*/
5882 0, /*nb_inplace_multiply*/
5883 0, /*nb_inplace_remainder*/
5884 0, /*nb_inplace_power*/
5885 0, /*nb_inplace_lshift*/
5886 0, /*nb_inplace_rshift*/
5887 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5888 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5889 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5890};
5891
5892static PySequenceMethods cpu_set_as_sequence = {
5893 (lenfunc)cpu_set_len, /* sq_length */
5894};
5895
5896static PyMethodDef cpu_set_methods[] = {
5897 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5898 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5899 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5900 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5901 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5902 {NULL, NULL} /* sentinel */
5903};
5904
5905static PyTypeObject cpu_set_type = {
5906 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5907 "posix.cpu_set", /* tp_name */
5908 sizeof(Py_cpu_set), /* tp_basicsize */
5909 0, /* tp_itemsize */
5910 /* methods */
5911 (destructor)cpu_set_dealloc, /* tp_dealloc */
5912 0, /* tp_print */
5913 0, /* tp_getattr */
5914 0, /* tp_setattr */
5915 0, /* tp_reserved */
5916 (reprfunc)cpu_set_repr, /* tp_repr */
5917 &cpu_set_as_number, /* tp_as_number */
5918 &cpu_set_as_sequence, /* tp_as_sequence */
5919 0, /* tp_as_mapping */
5920 PyObject_HashNotImplemented, /* tp_hash */
5921 0, /* tp_call */
5922 0, /* tp_str */
5923 PyObject_GenericGetAttr, /* tp_getattro */
5924 0, /* tp_setattro */
5925 0, /* tp_as_buffer */
5926 Py_TPFLAGS_DEFAULT, /* tp_flags */
5927 cpu_set_doc, /* tp_doc */
5928 0, /* tp_traverse */
5929 0, /* tp_clear */
5930 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5931 0, /* tp_weaklistoffset */
5932 0, /* tp_iter */
5933 0, /* tp_iternext */
5934 cpu_set_methods, /* tp_methods */
5935 0, /* tp_members */
5936 0, /* tp_getset */
5937 0, /* tp_base */
5938 0, /* tp_dict */
5939 0, /* tp_descr_get */
5940 0, /* tp_descr_set */
5941 0, /* tp_dictoffset */
5942 0, /* tp_init */
5943 PyType_GenericAlloc, /* tp_alloc */
5944 cpu_set_new, /* tp_new */
5945 PyObject_Del, /* tp_free */
5946};
5947
5948PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5949"sched_setaffinity(pid, cpu_set)\n\n\
5950Set the affinity of the process with PID *pid* to *cpu_set*.");
5951
5952static PyObject *
5953posix_sched_setaffinity(PyObject *self, PyObject *args)
5954{
5955 pid_t pid;
5956 Py_cpu_set *cpu_set;
5957
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005958 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005959 &pid, &cpu_set_type, &cpu_set))
5960 return NULL;
5961 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5962 return posix_error();
5963 Py_RETURN_NONE;
5964}
5965
5966PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5967"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5968Return the affinity of the process with PID *pid*.\n\
5969The returned cpu_set will be of size *ncpus*.");
5970
5971static PyObject *
5972posix_sched_getaffinity(PyObject *self, PyObject *args)
5973{
5974 pid_t pid;
5975 int ncpus;
5976 Py_cpu_set *res;
5977
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005978 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005979 &pid, &ncpus))
5980 return NULL;
5981 res = make_new_cpu_set(&cpu_set_type, ncpus);
5982 if (!res)
5983 return NULL;
5984 if (sched_getaffinity(pid, res->size, res->set)) {
5985 Py_DECREF(res);
5986 return posix_error();
5987 }
5988 return (PyObject *)res;
5989}
5990
Benjamin Peterson2740af82011-08-02 17:41:34 -05005991#endif /* HAVE_SCHED_SETAFFINITY */
5992
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005993#endif /* HAVE_SCHED_H */
5994
Neal Norwitzb59798b2003-03-21 01:43:31 +00005995/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005996/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5997#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005998#define DEV_PTY_FILE "/dev/ptc"
5999#define HAVE_DEV_PTMX
6000#else
6001#define DEV_PTY_FILE "/dev/ptmx"
6002#endif
6003
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006004#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006005#ifdef HAVE_PTY_H
6006#include <pty.h>
6007#else
6008#ifdef HAVE_LIBUTIL_H
6009#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006010#else
6011#ifdef HAVE_UTIL_H
6012#include <util.h>
6013#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006014#endif /* HAVE_LIBUTIL_H */
6015#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006016#ifdef HAVE_STROPTS_H
6017#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006018#endif
6019#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006020
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006021#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006022PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006023"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006024Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006025
6026static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006027posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006028{
Victor Stinner8c62be82010-05-06 00:08:46 +00006029 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006030#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006031 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006032#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006033#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006034 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006035#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006037#endif
6038#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006039
Thomas Wouters70c21a12000-07-14 14:28:33 +00006040#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6042 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006043#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006044 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6045 if (slave_name == NULL)
6046 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006047
Victor Stinner8c62be82010-05-06 00:08:46 +00006048 slave_fd = open(slave_name, O_RDWR);
6049 if (slave_fd < 0)
6050 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006051#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006052 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6053 if (master_fd < 0)
6054 return posix_error();
6055 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6056 /* change permission of slave */
6057 if (grantpt(master_fd) < 0) {
6058 PyOS_setsig(SIGCHLD, sig_saved);
6059 return posix_error();
6060 }
6061 /* unlock slave */
6062 if (unlockpt(master_fd) < 0) {
6063 PyOS_setsig(SIGCHLD, sig_saved);
6064 return posix_error();
6065 }
6066 PyOS_setsig(SIGCHLD, sig_saved);
6067 slave_name = ptsname(master_fd); /* get name of slave */
6068 if (slave_name == NULL)
6069 return posix_error();
6070 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6071 if (slave_fd < 0)
6072 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006073#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006074 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6075 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006076#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006078#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006079#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006080#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006081
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006083
Fred Drake8cef4cf2000-06-28 16:40:38 +00006084}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006085#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006086
6087#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006088PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006089"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006090Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6091Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006092To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006093
6094static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006095posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006096{
Victor Stinner8c62be82010-05-06 00:08:46 +00006097 int master_fd = -1, result = 0;
6098 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006099
Victor Stinner8c62be82010-05-06 00:08:46 +00006100 _PyImport_AcquireLock();
6101 pid = forkpty(&master_fd, NULL, NULL, NULL);
6102 if (pid == 0) {
6103 /* child: this clobbers and resets the import lock. */
6104 PyOS_AfterFork();
6105 } else {
6106 /* parent: release the import lock. */
6107 result = _PyImport_ReleaseLock();
6108 }
6109 if (pid == -1)
6110 return posix_error();
6111 if (result < 0) {
6112 /* Don't clobber the OSError if the fork failed. */
6113 PyErr_SetString(PyExc_RuntimeError,
6114 "not holding the import lock");
6115 return NULL;
6116 }
6117 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006118}
6119#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006120
Ross Lagerwall7807c352011-03-17 20:20:30 +02006121
Guido van Rossumad0ee831995-03-01 10:34:45 +00006122#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006124"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006125Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006126
Barry Warsaw53699e91996-12-10 23:23:01 +00006127static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006128posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006129{
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006131}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006132#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006133
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006134
Guido van Rossumad0ee831995-03-01 10:34:45 +00006135#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006137"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006138Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006139
Barry Warsaw53699e91996-12-10 23:23:01 +00006140static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006141posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006142{
Victor Stinner8c62be82010-05-06 00:08:46 +00006143 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006144}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006145#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006147
Guido van Rossumad0ee831995-03-01 10:34:45 +00006148#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006149PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006150"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006151Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006152
Barry Warsaw53699e91996-12-10 23:23:01 +00006153static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006154posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006155{
Victor Stinner8c62be82010-05-06 00:08:46 +00006156 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006157}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006158#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006160
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006161PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006162"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006163Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006164
Barry Warsaw53699e91996-12-10 23:23:01 +00006165static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006166posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006167{
Victor Stinner8c62be82010-05-06 00:08:46 +00006168 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006169}
6170
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006171#ifdef HAVE_GETGROUPLIST
6172PyDoc_STRVAR(posix_getgrouplist__doc__,
6173"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6174Returns a list of groups to which a user belongs.\n\n\
6175 user: username to lookup\n\
6176 group: base group id of the user");
6177
6178static PyObject *
6179posix_getgrouplist(PyObject *self, PyObject *args)
6180{
6181#ifdef NGROUPS_MAX
6182#define MAX_GROUPS NGROUPS_MAX
6183#else
6184 /* defined to be 16 on Solaris7, so this should be a small number */
6185#define MAX_GROUPS 64
6186#endif
6187
6188 const char *user;
6189 int i, ngroups;
6190 PyObject *list;
6191#ifdef __APPLE__
6192 int *groups, basegid;
6193#else
6194 gid_t *groups, basegid;
6195#endif
6196 ngroups = MAX_GROUPS;
6197
6198 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
6199 return NULL;
6200
6201#ifdef __APPLE__
6202 groups = PyMem_Malloc(ngroups * sizeof(int));
6203#else
6204 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6205#endif
6206 if (groups == NULL)
6207 return PyErr_NoMemory();
6208
6209 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6210 PyMem_Del(groups);
6211 return posix_error();
6212 }
6213
6214 list = PyList_New(ngroups);
6215 if (list == NULL) {
6216 PyMem_Del(groups);
6217 return NULL;
6218 }
6219
6220 for (i = 0; i < ngroups; i++) {
6221 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
6222 if (o == NULL) {
6223 Py_DECREF(list);
6224 PyMem_Del(groups);
6225 return NULL;
6226 }
6227 PyList_SET_ITEM(list, i, o);
6228 }
6229
6230 PyMem_Del(groups);
6231
6232 return list;
6233}
6234#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006235
Fred Drakec9680921999-12-13 16:37:25 +00006236#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006237PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006238"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006239Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006240
6241static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006242posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006243{
6244 PyObject *result = NULL;
6245
Fred Drakec9680921999-12-13 16:37:25 +00006246#ifdef NGROUPS_MAX
6247#define MAX_GROUPS NGROUPS_MAX
6248#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006249 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006250#define MAX_GROUPS 64
6251#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006253
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006254 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006255 * This is a helper variable to store the intermediate result when
6256 * that happens.
6257 *
6258 * To keep the code readable the OSX behaviour is unconditional,
6259 * according to the POSIX spec this should be safe on all unix-y
6260 * systems.
6261 */
6262 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006263 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006264
Victor Stinner8c62be82010-05-06 00:08:46 +00006265 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006266 if (n < 0) {
6267 if (errno == EINVAL) {
6268 n = getgroups(0, NULL);
6269 if (n == -1) {
6270 return posix_error();
6271 }
6272 if (n == 0) {
6273 /* Avoid malloc(0) */
6274 alt_grouplist = grouplist;
6275 } else {
6276 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6277 if (alt_grouplist == NULL) {
6278 errno = EINVAL;
6279 return posix_error();
6280 }
6281 n = getgroups(n, alt_grouplist);
6282 if (n == -1) {
6283 PyMem_Free(alt_grouplist);
6284 return posix_error();
6285 }
6286 }
6287 } else {
6288 return posix_error();
6289 }
6290 }
6291 result = PyList_New(n);
6292 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 int i;
6294 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006295 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006297 Py_DECREF(result);
6298 result = NULL;
6299 break;
Fred Drakec9680921999-12-13 16:37:25 +00006300 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006301 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006302 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006303 }
6304
6305 if (alt_grouplist != grouplist) {
6306 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006307 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006308
Fred Drakec9680921999-12-13 16:37:25 +00006309 return result;
6310}
6311#endif
6312
Antoine Pitroub7572f02009-12-02 20:46:48 +00006313#ifdef HAVE_INITGROUPS
6314PyDoc_STRVAR(posix_initgroups__doc__,
6315"initgroups(username, gid) -> None\n\n\
6316Call the system initgroups() to initialize the group access list with all of\n\
6317the groups of which the specified username is a member, plus the specified\n\
6318group id.");
6319
6320static PyObject *
6321posix_initgroups(PyObject *self, PyObject *args)
6322{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006323 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006325 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006326 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006327
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006328 if (!PyArg_ParseTuple(args, "O&l:initgroups",
6329 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006330 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006331 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006332
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006333 res = initgroups(username, (gid_t) gid);
6334 Py_DECREF(oname);
6335 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006336 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006337
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 Py_INCREF(Py_None);
6339 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006340}
6341#endif
6342
Martin v. Löwis606edc12002-06-13 21:09:11 +00006343#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006344PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006345"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006346Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006347
6348static PyObject *
6349posix_getpgid(PyObject *self, PyObject *args)
6350{
Victor Stinner8c62be82010-05-06 00:08:46 +00006351 pid_t pid, pgid;
6352 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6353 return NULL;
6354 pgid = getpgid(pid);
6355 if (pgid < 0)
6356 return posix_error();
6357 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006358}
6359#endif /* HAVE_GETPGID */
6360
6361
Guido van Rossumb6775db1994-08-01 11:34:53 +00006362#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006363PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006364"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006365Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006366
Barry Warsaw53699e91996-12-10 23:23:01 +00006367static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006368posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006369{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006370#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006372#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006373 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006374#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006375}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006376#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006377
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006378
Guido van Rossumb6775db1994-08-01 11:34:53 +00006379#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006380PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006381"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006382Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006383
Barry Warsaw53699e91996-12-10 23:23:01 +00006384static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006385posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006386{
Guido van Rossum64933891994-10-20 21:56:42 +00006387#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006388 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006389#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006391#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 return posix_error();
6393 Py_INCREF(Py_None);
6394 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006395}
6396
Guido van Rossumb6775db1994-08-01 11:34:53 +00006397#endif /* HAVE_SETPGRP */
6398
Guido van Rossumad0ee831995-03-01 10:34:45 +00006399#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006400
6401#ifdef MS_WINDOWS
6402#include <tlhelp32.h>
6403
6404static PyObject*
6405win32_getppid()
6406{
6407 HANDLE snapshot;
6408 pid_t mypid;
6409 PyObject* result = NULL;
6410 BOOL have_record;
6411 PROCESSENTRY32 pe;
6412
6413 mypid = getpid(); /* This function never fails */
6414
6415 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6416 if (snapshot == INVALID_HANDLE_VALUE)
6417 return PyErr_SetFromWindowsErr(GetLastError());
6418
6419 pe.dwSize = sizeof(pe);
6420 have_record = Process32First(snapshot, &pe);
6421 while (have_record) {
6422 if (mypid == (pid_t)pe.th32ProcessID) {
6423 /* We could cache the ulong value in a static variable. */
6424 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6425 break;
6426 }
6427
6428 have_record = Process32Next(snapshot, &pe);
6429 }
6430
6431 /* If our loop exits and our pid was not found (result will be NULL)
6432 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6433 * error anyway, so let's raise it. */
6434 if (!result)
6435 result = PyErr_SetFromWindowsErr(GetLastError());
6436
6437 CloseHandle(snapshot);
6438
6439 return result;
6440}
6441#endif /*MS_WINDOWS*/
6442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006443PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006444"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006445Return the parent's process id. If the parent process has already exited,\n\
6446Windows machines will still return its id; others systems will return the id\n\
6447of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006448
Barry Warsaw53699e91996-12-10 23:23:01 +00006449static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006450posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006451{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006452#ifdef MS_WINDOWS
6453 return win32_getppid();
6454#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006456#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006457}
6458#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006460
Fred Drake12c6e2d1999-12-14 21:25:03 +00006461#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006462PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006463"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006464Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006465
6466static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006467posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006468{
Victor Stinner8c62be82010-05-06 00:08:46 +00006469 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006470#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006471 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006472 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006473
6474 if (GetUserNameW(user_name, &num_chars)) {
6475 /* num_chars is the number of unicode chars plus null terminator */
6476 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006477 }
6478 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006479 result = PyErr_SetFromWindowsErr(GetLastError());
6480#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 char *name;
6482 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006483
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 errno = 0;
6485 name = getlogin();
6486 if (name == NULL) {
6487 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006488 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006489 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006490 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 }
6492 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006493 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006495#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006496 return result;
6497}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006498#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006499
Guido van Rossumad0ee831995-03-01 10:34:45 +00006500#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006501PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006502"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006503Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006504
Barry Warsaw53699e91996-12-10 23:23:01 +00006505static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006506posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006507{
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006509}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006510#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006511
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006512
Guido van Rossumad0ee831995-03-01 10:34:45 +00006513#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006514PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006515"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006516Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006517
Barry Warsaw53699e91996-12-10 23:23:01 +00006518static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006519posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006520{
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 pid_t pid;
6522 int sig;
6523 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6524 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006525#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006526 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6527 APIRET rc;
6528 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006529 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006530
6531 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6532 APIRET rc;
6533 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006534 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006535
6536 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006537 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006538#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 if (kill(pid, sig) == -1)
6540 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006541#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 Py_INCREF(Py_None);
6543 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006544}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006545#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006546
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006547#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006548PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006549"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006550Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006551
6552static PyObject *
6553posix_killpg(PyObject *self, PyObject *args)
6554{
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 int sig;
6556 pid_t pgid;
6557 /* XXX some man pages make the `pgid` parameter an int, others
6558 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6559 take the same type. Moreover, pid_t is always at least as wide as
6560 int (else compilation of this module fails), which is safe. */
6561 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6562 return NULL;
6563 if (killpg(pgid, sig) == -1)
6564 return posix_error();
6565 Py_INCREF(Py_None);
6566 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006567}
6568#endif
6569
Brian Curtineb24d742010-04-12 17:16:38 +00006570#ifdef MS_WINDOWS
6571PyDoc_STRVAR(win32_kill__doc__,
6572"kill(pid, sig)\n\n\
6573Kill a process with a signal.");
6574
6575static PyObject *
6576win32_kill(PyObject *self, PyObject *args)
6577{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006578 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006579 DWORD pid, sig, err;
6580 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006581
Victor Stinner8c62be82010-05-06 00:08:46 +00006582 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6583 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006584
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 /* Console processes which share a common console can be sent CTRL+C or
6586 CTRL+BREAK events, provided they handle said events. */
6587 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6588 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6589 err = GetLastError();
6590 PyErr_SetFromWindowsErr(err);
6591 }
6592 else
6593 Py_RETURN_NONE;
6594 }
Brian Curtineb24d742010-04-12 17:16:38 +00006595
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6597 attempt to open and terminate the process. */
6598 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6599 if (handle == NULL) {
6600 err = GetLastError();
6601 return PyErr_SetFromWindowsErr(err);
6602 }
Brian Curtineb24d742010-04-12 17:16:38 +00006603
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 if (TerminateProcess(handle, sig) == 0) {
6605 err = GetLastError();
6606 result = PyErr_SetFromWindowsErr(err);
6607 } else {
6608 Py_INCREF(Py_None);
6609 result = Py_None;
6610 }
Brian Curtineb24d742010-04-12 17:16:38 +00006611
Victor Stinner8c62be82010-05-06 00:08:46 +00006612 CloseHandle(handle);
6613 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006614}
6615#endif /* MS_WINDOWS */
6616
Guido van Rossumc0125471996-06-28 18:55:32 +00006617#ifdef HAVE_PLOCK
6618
6619#ifdef HAVE_SYS_LOCK_H
6620#include <sys/lock.h>
6621#endif
6622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006624"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006625Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006626
Barry Warsaw53699e91996-12-10 23:23:01 +00006627static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006628posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006629{
Victor Stinner8c62be82010-05-06 00:08:46 +00006630 int op;
6631 if (!PyArg_ParseTuple(args, "i:plock", &op))
6632 return NULL;
6633 if (plock(op) == -1)
6634 return posix_error();
6635 Py_INCREF(Py_None);
6636 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006637}
6638#endif
6639
Guido van Rossumb6775db1994-08-01 11:34:53 +00006640#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006641PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006642"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006643Set the current process's user id.");
6644
Barry Warsaw53699e91996-12-10 23:23:01 +00006645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006646posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006647{
Victor Stinner8c62be82010-05-06 00:08:46 +00006648 long uid_arg;
6649 uid_t uid;
6650 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6651 return NULL;
6652 uid = uid_arg;
6653 if (uid != uid_arg) {
6654 PyErr_SetString(PyExc_OverflowError, "user id too big");
6655 return NULL;
6656 }
6657 if (setuid(uid) < 0)
6658 return posix_error();
6659 Py_INCREF(Py_None);
6660 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006661}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006662#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006664
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006665#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006666PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006667"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006668Set the current process's effective user id.");
6669
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006670static PyObject *
6671posix_seteuid (PyObject *self, PyObject *args)
6672{
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 long euid_arg;
6674 uid_t euid;
6675 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6676 return NULL;
6677 euid = euid_arg;
6678 if (euid != euid_arg) {
6679 PyErr_SetString(PyExc_OverflowError, "user id too big");
6680 return NULL;
6681 }
6682 if (seteuid(euid) < 0) {
6683 return posix_error();
6684 } else {
6685 Py_INCREF(Py_None);
6686 return Py_None;
6687 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006688}
6689#endif /* HAVE_SETEUID */
6690
6691#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006692PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006693"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006694Set the current process's effective group id.");
6695
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006696static PyObject *
6697posix_setegid (PyObject *self, PyObject *args)
6698{
Victor Stinner8c62be82010-05-06 00:08:46 +00006699 long egid_arg;
6700 gid_t egid;
6701 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6702 return NULL;
6703 egid = egid_arg;
6704 if (egid != egid_arg) {
6705 PyErr_SetString(PyExc_OverflowError, "group id too big");
6706 return NULL;
6707 }
6708 if (setegid(egid) < 0) {
6709 return posix_error();
6710 } else {
6711 Py_INCREF(Py_None);
6712 return Py_None;
6713 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006714}
6715#endif /* HAVE_SETEGID */
6716
6717#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006718PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006719"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006720Set the current process's real and effective user ids.");
6721
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006722static PyObject *
6723posix_setreuid (PyObject *self, PyObject *args)
6724{
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 long ruid_arg, euid_arg;
6726 uid_t ruid, euid;
6727 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6728 return NULL;
6729 if (ruid_arg == -1)
6730 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6731 else
6732 ruid = ruid_arg; /* otherwise, assign from our long */
6733 if (euid_arg == -1)
6734 euid = (uid_t)-1;
6735 else
6736 euid = euid_arg;
6737 if ((euid_arg != -1 && euid != euid_arg) ||
6738 (ruid_arg != -1 && ruid != ruid_arg)) {
6739 PyErr_SetString(PyExc_OverflowError, "user id too big");
6740 return NULL;
6741 }
6742 if (setreuid(ruid, euid) < 0) {
6743 return posix_error();
6744 } else {
6745 Py_INCREF(Py_None);
6746 return Py_None;
6747 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006748}
6749#endif /* HAVE_SETREUID */
6750
6751#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006752PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006753"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006754Set the current process's real and effective group ids.");
6755
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006756static PyObject *
6757posix_setregid (PyObject *self, PyObject *args)
6758{
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 long rgid_arg, egid_arg;
6760 gid_t rgid, egid;
6761 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6762 return NULL;
6763 if (rgid_arg == -1)
6764 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6765 else
6766 rgid = rgid_arg; /* otherwise, assign from our long */
6767 if (egid_arg == -1)
6768 egid = (gid_t)-1;
6769 else
6770 egid = egid_arg;
6771 if ((egid_arg != -1 && egid != egid_arg) ||
6772 (rgid_arg != -1 && rgid != rgid_arg)) {
6773 PyErr_SetString(PyExc_OverflowError, "group id too big");
6774 return NULL;
6775 }
6776 if (setregid(rgid, egid) < 0) {
6777 return posix_error();
6778 } else {
6779 Py_INCREF(Py_None);
6780 return Py_None;
6781 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006782}
6783#endif /* HAVE_SETREGID */
6784
Guido van Rossumb6775db1994-08-01 11:34:53 +00006785#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006786PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006787"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006788Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006789
Barry Warsaw53699e91996-12-10 23:23:01 +00006790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006791posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006792{
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 long gid_arg;
6794 gid_t gid;
6795 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6796 return NULL;
6797 gid = gid_arg;
6798 if (gid != gid_arg) {
6799 PyErr_SetString(PyExc_OverflowError, "group id too big");
6800 return NULL;
6801 }
6802 if (setgid(gid) < 0)
6803 return posix_error();
6804 Py_INCREF(Py_None);
6805 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006806}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006807#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006808
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006809#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006810PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006811"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006813
6814static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006815posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006816{
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 int i, len;
6818 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006819
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 if (!PySequence_Check(groups)) {
6821 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6822 return NULL;
6823 }
6824 len = PySequence_Size(groups);
6825 if (len > MAX_GROUPS) {
6826 PyErr_SetString(PyExc_ValueError, "too many groups");
6827 return NULL;
6828 }
6829 for(i = 0; i < len; i++) {
6830 PyObject *elem;
6831 elem = PySequence_GetItem(groups, i);
6832 if (!elem)
6833 return NULL;
6834 if (!PyLong_Check(elem)) {
6835 PyErr_SetString(PyExc_TypeError,
6836 "groups must be integers");
6837 Py_DECREF(elem);
6838 return NULL;
6839 } else {
6840 unsigned long x = PyLong_AsUnsignedLong(elem);
6841 if (PyErr_Occurred()) {
6842 PyErr_SetString(PyExc_TypeError,
6843 "group id too big");
6844 Py_DECREF(elem);
6845 return NULL;
6846 }
6847 grouplist[i] = x;
6848 /* read back the value to see if it fitted in gid_t */
6849 if (grouplist[i] != x) {
6850 PyErr_SetString(PyExc_TypeError,
6851 "group id too big");
6852 Py_DECREF(elem);
6853 return NULL;
6854 }
6855 }
6856 Py_DECREF(elem);
6857 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006858
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 if (setgroups(len, grouplist) < 0)
6860 return posix_error();
6861 Py_INCREF(Py_None);
6862 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006863}
6864#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006865
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6867static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006868wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006869{
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 PyObject *result;
6871 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006872 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006873
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 if (pid == -1)
6875 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 if (struct_rusage == NULL) {
6878 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6879 if (m == NULL)
6880 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006881 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006882 Py_DECREF(m);
6883 if (struct_rusage == NULL)
6884 return NULL;
6885 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6888 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6889 if (!result)
6890 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006891
6892#ifndef doubletime
6893#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6894#endif
6895
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006897 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006899 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006900#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6902 SET_INT(result, 2, ru->ru_maxrss);
6903 SET_INT(result, 3, ru->ru_ixrss);
6904 SET_INT(result, 4, ru->ru_idrss);
6905 SET_INT(result, 5, ru->ru_isrss);
6906 SET_INT(result, 6, ru->ru_minflt);
6907 SET_INT(result, 7, ru->ru_majflt);
6908 SET_INT(result, 8, ru->ru_nswap);
6909 SET_INT(result, 9, ru->ru_inblock);
6910 SET_INT(result, 10, ru->ru_oublock);
6911 SET_INT(result, 11, ru->ru_msgsnd);
6912 SET_INT(result, 12, ru->ru_msgrcv);
6913 SET_INT(result, 13, ru->ru_nsignals);
6914 SET_INT(result, 14, ru->ru_nvcsw);
6915 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006916#undef SET_INT
6917
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 if (PyErr_Occurred()) {
6919 Py_DECREF(result);
6920 return NULL;
6921 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006922
Victor Stinner8c62be82010-05-06 00:08:46 +00006923 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006924}
6925#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6926
6927#ifdef HAVE_WAIT3
6928PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006929"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006930Wait for completion of a child process.");
6931
6932static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006933posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934{
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 pid_t pid;
6936 int options;
6937 struct rusage ru;
6938 WAIT_TYPE status;
6939 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006940
Victor Stinner4195b5c2012-02-08 23:03:19 +01006941 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006942 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006943
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 Py_BEGIN_ALLOW_THREADS
6945 pid = wait3(&status, options, &ru);
6946 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006947
Victor Stinner4195b5c2012-02-08 23:03:19 +01006948 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006949}
6950#endif /* HAVE_WAIT3 */
6951
6952#ifdef HAVE_WAIT4
6953PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006954"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006955Wait for completion of a given child process.");
6956
6957static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006958posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006959{
Victor Stinner8c62be82010-05-06 00:08:46 +00006960 pid_t pid;
6961 int options;
6962 struct rusage ru;
6963 WAIT_TYPE status;
6964 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006965
Victor Stinner4195b5c2012-02-08 23:03:19 +01006966 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006968
Victor Stinner8c62be82010-05-06 00:08:46 +00006969 Py_BEGIN_ALLOW_THREADS
6970 pid = wait4(pid, &status, options, &ru);
6971 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006972
Victor Stinner4195b5c2012-02-08 23:03:19 +01006973 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006974}
6975#endif /* HAVE_WAIT4 */
6976
Ross Lagerwall7807c352011-03-17 20:20:30 +02006977#if defined(HAVE_WAITID) && !defined(__APPLE__)
6978PyDoc_STRVAR(posix_waitid__doc__,
6979"waitid(idtype, id, options) -> waitid_result\n\n\
6980Wait for the completion of one or more child processes.\n\n\
6981idtype can be P_PID, P_PGID or P_ALL.\n\
6982id specifies the pid to wait on.\n\
6983options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6984or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6985Returns either waitid_result or None if WNOHANG is specified and there are\n\
6986no children in a waitable state.");
6987
6988static PyObject *
6989posix_waitid(PyObject *self, PyObject *args)
6990{
6991 PyObject *result;
6992 idtype_t idtype;
6993 id_t id;
6994 int options, res;
6995 siginfo_t si;
6996 si.si_pid = 0;
6997 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6998 return NULL;
6999 Py_BEGIN_ALLOW_THREADS
7000 res = waitid(idtype, id, &si, options);
7001 Py_END_ALLOW_THREADS
7002 if (res == -1)
7003 return posix_error();
7004
7005 if (si.si_pid == 0)
7006 Py_RETURN_NONE;
7007
7008 result = PyStructSequence_New(&WaitidResultType);
7009 if (!result)
7010 return NULL;
7011
7012 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
7013 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
7014 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7015 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7016 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7017 if (PyErr_Occurred()) {
7018 Py_DECREF(result);
7019 return NULL;
7020 }
7021
7022 return result;
7023}
7024#endif
7025
Guido van Rossumb6775db1994-08-01 11:34:53 +00007026#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007027PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007028"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007029Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007030
Barry Warsaw53699e91996-12-10 23:23:01 +00007031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007032posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007033{
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 pid_t pid;
7035 int options;
7036 WAIT_TYPE status;
7037 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007038
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7040 return NULL;
7041 Py_BEGIN_ALLOW_THREADS
7042 pid = waitpid(pid, &status, options);
7043 Py_END_ALLOW_THREADS
7044 if (pid == -1)
7045 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007046
Victor Stinner8c62be82010-05-06 00:08:46 +00007047 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007048}
7049
Tim Petersab034fa2002-02-01 11:27:43 +00007050#elif defined(HAVE_CWAIT)
7051
7052/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007053PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007054"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007055"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007056
7057static PyObject *
7058posix_waitpid(PyObject *self, PyObject *args)
7059{
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 Py_intptr_t pid;
7061 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007062
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7064 return NULL;
7065 Py_BEGIN_ALLOW_THREADS
7066 pid = _cwait(&status, pid, options);
7067 Py_END_ALLOW_THREADS
7068 if (pid == -1)
7069 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007070
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 /* shift the status left a byte so this is more like the POSIX waitpid */
7072 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007073}
7074#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007075
Guido van Rossumad0ee831995-03-01 10:34:45 +00007076#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007077PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007078"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007079Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007080
Barry Warsaw53699e91996-12-10 23:23:01 +00007081static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007082posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007083{
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 pid_t pid;
7085 WAIT_TYPE status;
7086 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007087
Victor Stinner8c62be82010-05-06 00:08:46 +00007088 Py_BEGIN_ALLOW_THREADS
7089 pid = wait(&status);
7090 Py_END_ALLOW_THREADS
7091 if (pid == -1)
7092 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007093
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007095}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007096#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007098
Larry Hastings9cf065c2012-06-22 16:30:09 -07007099#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7100PyDoc_STRVAR(readlink__doc__,
7101"readlink(path, *, dir_fd=None) -> path\n\n\
7102Return a string representing the path to which the symbolic link points.\n\
7103\n\
7104If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7105 and path should be relative; path will then be relative to that directory.\n\
7106dir_fd may not be implemented on your platform.\n\
7107 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007108#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007109
Guido van Rossumb6775db1994-08-01 11:34:53 +00007110#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007111
Barry Warsaw53699e91996-12-10 23:23:01 +00007112static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007114{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007115 path_t path;
7116 int dir_fd = DEFAULT_DIR_FD;
7117 char buffer[MAXPATHLEN];
7118 ssize_t length;
7119 PyObject *return_value = NULL;
7120 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007121
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122 memset(&path, 0, sizeof(path));
7123 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7124 path_converter, &path,
7125#ifdef HAVE_READLINKAT
7126 dir_fd_converter, &dir_fd
7127#else
7128 dir_fd_unavailable, &dir_fd
7129#endif
7130 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007131 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007132
Victor Stinner8c62be82010-05-06 00:08:46 +00007133 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134#ifdef HAVE_READLINKAT
7135 if (dir_fd != DEFAULT_DIR_FD)
7136 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007137 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007138#endif
7139 length = readlink(path.narrow, buffer, sizeof(buffer));
7140 Py_END_ALLOW_THREADS
7141
7142 if (length < 0) {
7143 return_value = path_posix_error("readlink", &path);
7144 goto exit;
7145 }
7146
7147 if (PyUnicode_Check(path.object))
7148 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7149 else
7150 return_value = PyBytes_FromStringAndSize(buffer, length);
7151exit:
7152 path_cleanup(&path);
7153 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007154}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007155
7156
Guido van Rossumb6775db1994-08-01 11:34:53 +00007157#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007159
Larry Hastings9cf065c2012-06-22 16:30:09 -07007160#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007161PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007162"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7163Create a symbolic link pointing to src named dst.\n\n\
7164target_is_directory is required on Windows if the target is to be\n\
7165 interpreted as a directory. (On Windows, symlink requires\n\
7166 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7167 target_is_directory is ignored on non-Windows platforms.\n\
7168\n\
7169If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7170 and path should be relative; path will then be relative to that directory.\n\
7171dir_fd may not be implemented on your platform.\n\
7172 If it is unavailable, using it will raise a NotImplementedError.");
7173
7174#if defined(MS_WINDOWS)
7175
7176/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7177static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7178static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7179static int
7180check_CreateSymbolicLink()
7181{
7182 HINSTANCE hKernel32;
7183 /* only recheck */
7184 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7185 return 1;
7186 hKernel32 = GetModuleHandleW(L"KERNEL32");
7187 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7188 "CreateSymbolicLinkW");
7189 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7190 "CreateSymbolicLinkA");
7191 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7192}
7193
7194#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007195
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007196static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007197posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007198{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007199 path_t src;
7200 path_t dst;
7201 int dir_fd = DEFAULT_DIR_FD;
7202 int target_is_directory = 0;
7203 static char *keywords[] = {"src", "dst", "target_is_directory",
7204 "dir_fd", NULL};
7205 PyObject *return_value;
7206#ifdef MS_WINDOWS
7207 DWORD result;
7208#else
7209 int result;
7210#endif
7211
7212 memset(&src, 0, sizeof(src));
7213 src.argument_name = "src";
7214 memset(&dst, 0, sizeof(dst));
7215 dst.argument_name = "dst";
7216
7217#ifdef MS_WINDOWS
7218 if (!check_CreateSymbolicLink()) {
7219 PyErr_SetString(PyExc_NotImplementedError,
7220 "CreateSymbolicLink functions not found");
7221 return NULL;
7222 }
7223 if (!win32_can_symlink) {
7224 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
7225 return NULL;
7226 }
7227#endif
7228
7229 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7230 keywords,
7231 path_converter, &src,
7232 path_converter, &dst,
7233 &target_is_directory,
7234#ifdef HAVE_SYMLINKAT
7235 dir_fd_converter, &dir_fd
7236#else
7237 dir_fd_unavailable, &dir_fd
7238#endif
7239 ))
7240 return NULL;
7241
7242 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7243 PyErr_SetString(PyExc_ValueError,
7244 "symlink: src and dst must be the same type");
7245 return_value = NULL;
7246 goto exit;
7247 }
7248
7249#ifdef MS_WINDOWS
7250 Py_BEGIN_ALLOW_THREADS
7251 if (dst.wide)
7252 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7253 target_is_directory);
7254 else
7255 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7256 target_is_directory);
7257 Py_END_ALLOW_THREADS
7258
7259 if (!result) {
7260 return_value = win32_error_object("symlink", src.object);
7261 goto exit;
7262 }
7263
7264#else
7265
7266 Py_BEGIN_ALLOW_THREADS
7267#if HAVE_SYMLINKAT
7268 if (dir_fd != DEFAULT_DIR_FD)
7269 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7270 else
7271#endif
7272 result = symlink(src.narrow, dst.narrow);
7273 Py_END_ALLOW_THREADS
7274
7275 if (result) {
7276 return_value = path_error("symlink", &dst);
7277 goto exit;
7278 }
7279#endif
7280
7281 return_value = Py_None;
7282 Py_INCREF(Py_None);
7283 goto exit; /* silence "unused label" warning */
7284exit:
7285 path_cleanup(&src);
7286 path_cleanup(&dst);
7287 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007288}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007289
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007290#endif /* HAVE_SYMLINK */
7291
Larry Hastings9cf065c2012-06-22 16:30:09 -07007292
Brian Curtind40e6f72010-07-08 21:39:08 +00007293#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7294
Brian Curtind40e6f72010-07-08 21:39:08 +00007295static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007296win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007297{
7298 wchar_t *path;
7299 DWORD n_bytes_returned;
7300 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007301 PyObject *po, *result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007302 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007303 HANDLE reparse_point_handle;
7304
7305 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7306 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7307 wchar_t *print_name;
7308
Larry Hastings9cf065c2012-06-22 16:30:09 -07007309 static char *keywords[] = {"path", "dir_fd", NULL};
7310
7311 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7312 &po,
7313 dir_fd_unavailable, &dir_fd
7314 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007315 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007316
Victor Stinnereb5657a2011-09-30 01:44:27 +02007317 path = PyUnicode_AsUnicode(po);
7318 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007319 return NULL;
7320
7321 /* First get a handle to the reparse point */
7322 Py_BEGIN_ALLOW_THREADS
7323 reparse_point_handle = CreateFileW(
7324 path,
7325 0,
7326 0,
7327 0,
7328 OPEN_EXISTING,
7329 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7330 0);
7331 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007332
Brian Curtind40e6f72010-07-08 21:39:08 +00007333 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007334 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007335
Brian Curtind40e6f72010-07-08 21:39:08 +00007336 Py_BEGIN_ALLOW_THREADS
7337 /* New call DeviceIoControl to read the reparse point */
7338 io_result = DeviceIoControl(
7339 reparse_point_handle,
7340 FSCTL_GET_REPARSE_POINT,
7341 0, 0, /* in buffer */
7342 target_buffer, sizeof(target_buffer),
7343 &n_bytes_returned,
7344 0 /* we're not using OVERLAPPED_IO */
7345 );
7346 CloseHandle(reparse_point_handle);
7347 Py_END_ALLOW_THREADS
7348
7349 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007350 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007351
7352 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7353 {
7354 PyErr_SetString(PyExc_ValueError,
7355 "not a symbolic link");
7356 return NULL;
7357 }
Brian Curtin74e45612010-07-09 15:58:59 +00007358 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7359 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7360
7361 result = PyUnicode_FromWideChar(print_name,
7362 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007363 return result;
7364}
7365
7366#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7367
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007368
7369#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00007370#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7371static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007372system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007373{
7374 ULONG value = 0;
7375
7376 Py_BEGIN_ALLOW_THREADS
7377 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7378 Py_END_ALLOW_THREADS
7379
7380 return value;
7381}
7382
7383static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007384posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007385{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007386 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00007387 return Py_BuildValue("ddddd",
7388 (double)0 /* t.tms_utime / HZ */,
7389 (double)0 /* t.tms_stime / HZ */,
7390 (double)0 /* t.tms_cutime / HZ */,
7391 (double)0 /* t.tms_cstime / HZ */,
7392 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007393}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007394#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007395#define NEED_TICKS_PER_SECOND
7396static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00007397static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007398posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00007399{
Victor Stinner8c62be82010-05-06 00:08:46 +00007400 struct tms t;
7401 clock_t c;
7402 errno = 0;
7403 c = times(&t);
7404 if (c == (clock_t) -1)
7405 return posix_error();
7406 return Py_BuildValue("ddddd",
7407 (double)t.tms_utime / ticks_per_second,
7408 (double)t.tms_stime / ticks_per_second,
7409 (double)t.tms_cutime / ticks_per_second,
7410 (double)t.tms_cstime / ticks_per_second,
7411 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00007412}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007413#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007414#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007415
7416
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007417#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007418#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00007419static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007420posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007421{
Victor Stinner8c62be82010-05-06 00:08:46 +00007422 FILETIME create, exit, kernel, user;
7423 HANDLE hProc;
7424 hProc = GetCurrentProcess();
7425 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7426 /* The fields of a FILETIME structure are the hi and lo part
7427 of a 64-bit value expressed in 100 nanosecond units.
7428 1e7 is one second in such units; 1e-7 the inverse.
7429 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7430 */
7431 return Py_BuildValue(
7432 "ddddd",
7433 (double)(user.dwHighDateTime*429.4967296 +
7434 user.dwLowDateTime*1e-7),
7435 (double)(kernel.dwHighDateTime*429.4967296 +
7436 kernel.dwLowDateTime*1e-7),
7437 (double)0,
7438 (double)0,
7439 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007440}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007441#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007442
7443#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007444PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007445"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007446Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007447#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007448
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007449
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007450#ifdef HAVE_GETSID
7451PyDoc_STRVAR(posix_getsid__doc__,
7452"getsid(pid) -> sid\n\n\
7453Call the system call getsid().");
7454
7455static PyObject *
7456posix_getsid(PyObject *self, PyObject *args)
7457{
Victor Stinner8c62be82010-05-06 00:08:46 +00007458 pid_t pid;
7459 int sid;
7460 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7461 return NULL;
7462 sid = getsid(pid);
7463 if (sid < 0)
7464 return posix_error();
7465 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007466}
7467#endif /* HAVE_GETSID */
7468
7469
Guido van Rossumb6775db1994-08-01 11:34:53 +00007470#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007471PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007472"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007473Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007474
Barry Warsaw53699e91996-12-10 23:23:01 +00007475static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007476posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007477{
Victor Stinner8c62be82010-05-06 00:08:46 +00007478 if (setsid() < 0)
7479 return posix_error();
7480 Py_INCREF(Py_None);
7481 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007482}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007483#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007484
Guido van Rossumb6775db1994-08-01 11:34:53 +00007485#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007486PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007487"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007488Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007489
Barry Warsaw53699e91996-12-10 23:23:01 +00007490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007491posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007492{
Victor Stinner8c62be82010-05-06 00:08:46 +00007493 pid_t pid;
7494 int pgrp;
7495 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7496 return NULL;
7497 if (setpgid(pid, pgrp) < 0)
7498 return posix_error();
7499 Py_INCREF(Py_None);
7500 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007501}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007502#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007504
Guido van Rossumb6775db1994-08-01 11:34:53 +00007505#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007506PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007507"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007508Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007509
Barry Warsaw53699e91996-12-10 23:23:01 +00007510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007511posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007512{
Victor Stinner8c62be82010-05-06 00:08:46 +00007513 int fd;
7514 pid_t pgid;
7515 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7516 return NULL;
7517 pgid = tcgetpgrp(fd);
7518 if (pgid < 0)
7519 return posix_error();
7520 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007521}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007522#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007524
Guido van Rossumb6775db1994-08-01 11:34:53 +00007525#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007526PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007527"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007528Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007529
Barry Warsaw53699e91996-12-10 23:23:01 +00007530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007531posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007532{
Victor Stinner8c62be82010-05-06 00:08:46 +00007533 int fd;
7534 pid_t pgid;
7535 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7536 return NULL;
7537 if (tcsetpgrp(fd, pgid) < 0)
7538 return posix_error();
7539 Py_INCREF(Py_None);
7540 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007541}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007542#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007543
Guido van Rossum687dd131993-05-17 08:34:16 +00007544/* Functions acting on file descriptors */
7545
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007546PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007547"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7548Open a file for low level IO. Returns a file handle (integer).\n\
7549\n\
7550If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7551 and path should be relative; path will then be relative to that directory.\n\
7552dir_fd may not be implemented on your platform.\n\
7553 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007554
Barry Warsaw53699e91996-12-10 23:23:01 +00007555static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007556posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007557{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007558 path_t path;
7559 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007560 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007561 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007563 PyObject *return_value = NULL;
7564 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007565
Larry Hastings9cf065c2012-06-22 16:30:09 -07007566 memset(&path, 0, sizeof(path));
7567 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7568 path_converter, &path,
7569 &flags, &mode,
7570#ifdef HAVE_OPENAT
7571 dir_fd_converter, &dir_fd
7572#else
7573 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007574#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007575 ))
7576 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007577
Victor Stinner8c62be82010-05-06 00:08:46 +00007578 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007579#ifdef MS_WINDOWS
7580 if (path.wide)
7581 fd = _wopen(path.wide, flags, mode);
7582 else
7583#endif
7584#ifdef HAVE_OPENAT
7585 if (dir_fd != DEFAULT_DIR_FD)
7586 fd = openat(dir_fd, path.narrow, flags, mode);
7587 else
7588#endif
7589 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007590 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007591
Larry Hastings9cf065c2012-06-22 16:30:09 -07007592 if (fd == -1) {
7593#ifdef MS_WINDOWS
7594 /* force use of posix_error here for exact backwards compatibility */
7595 if (path.wide)
7596 return_value = posix_error();
7597 else
7598#endif
7599 return_value = path_error("open", &path);
7600 goto exit;
7601 }
7602
7603 return_value = PyLong_FromLong((long)fd);
7604
7605exit:
7606 path_cleanup(&path);
7607 return return_value;
7608}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007609
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007610PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007611"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007612Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007613
Barry Warsaw53699e91996-12-10 23:23:01 +00007614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007615posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007616{
Victor Stinner8c62be82010-05-06 00:08:46 +00007617 int fd, res;
7618 if (!PyArg_ParseTuple(args, "i:close", &fd))
7619 return NULL;
7620 if (!_PyVerify_fd(fd))
7621 return posix_error();
7622 Py_BEGIN_ALLOW_THREADS
7623 res = close(fd);
7624 Py_END_ALLOW_THREADS
7625 if (res < 0)
7626 return posix_error();
7627 Py_INCREF(Py_None);
7628 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007629}
7630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007631
Victor Stinner8c62be82010-05-06 00:08:46 +00007632PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007633"closerange(fd_low, fd_high)\n\n\
7634Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7635
7636static PyObject *
7637posix_closerange(PyObject *self, PyObject *args)
7638{
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 int fd_from, fd_to, i;
7640 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7641 return NULL;
7642 Py_BEGIN_ALLOW_THREADS
7643 for (i = fd_from; i < fd_to; i++)
7644 if (_PyVerify_fd(i))
7645 close(i);
7646 Py_END_ALLOW_THREADS
7647 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007648}
7649
7650
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007651PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007652"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007653Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007654
Barry Warsaw53699e91996-12-10 23:23:01 +00007655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007656posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007657{
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 int fd;
7659 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7660 return NULL;
7661 if (!_PyVerify_fd(fd))
7662 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007663 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 if (fd < 0)
7665 return posix_error();
7666 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007667}
7668
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007669
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007670PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007671"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007672Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007673
Barry Warsaw53699e91996-12-10 23:23:01 +00007674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007675posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007676{
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 int fd, fd2, res;
7678 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7679 return NULL;
7680 if (!_PyVerify_fd_dup2(fd, fd2))
7681 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007682 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007683 if (res < 0)
7684 return posix_error();
7685 Py_INCREF(Py_None);
7686 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007687}
7688
Ross Lagerwall7807c352011-03-17 20:20:30 +02007689#ifdef HAVE_LOCKF
7690PyDoc_STRVAR(posix_lockf__doc__,
7691"lockf(fd, cmd, len)\n\n\
7692Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7693fd is an open file descriptor.\n\
7694cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7695F_TEST.\n\
7696len specifies the section of the file to lock.");
7697
7698static PyObject *
7699posix_lockf(PyObject *self, PyObject *args)
7700{
7701 int fd, cmd, res;
7702 off_t len;
7703 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7704 &fd, &cmd, _parse_off_t, &len))
7705 return NULL;
7706
7707 Py_BEGIN_ALLOW_THREADS
7708 res = lockf(fd, cmd, len);
7709 Py_END_ALLOW_THREADS
7710
7711 if (res < 0)
7712 return posix_error();
7713
7714 Py_RETURN_NONE;
7715}
7716#endif
7717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007718
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007719PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007720"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007721Set the current position of a file descriptor.\n\
7722Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007723
Barry Warsaw53699e91996-12-10 23:23:01 +00007724static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007725posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007726{
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007728#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007730#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007732#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007733 PyObject *posobj;
7734 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007735 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007736#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7738 switch (how) {
7739 case 0: how = SEEK_SET; break;
7740 case 1: how = SEEK_CUR; break;
7741 case 2: how = SEEK_END; break;
7742 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007743#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007744
Ross Lagerwall8e749672011-03-17 21:54:07 +02007745#if !defined(HAVE_LARGEFILE_SUPPORT)
7746 pos = PyLong_AsLong(posobj);
7747#else
7748 pos = PyLong_AsLongLong(posobj);
7749#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 if (PyErr_Occurred())
7751 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007752
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 if (!_PyVerify_fd(fd))
7754 return posix_error();
7755 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007756#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007757 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007758#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007759 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007760#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 Py_END_ALLOW_THREADS
7762 if (res < 0)
7763 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007764
7765#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007767#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007769#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007770}
7771
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007772
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007773PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007774"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007775Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007776
Barry Warsaw53699e91996-12-10 23:23:01 +00007777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007778posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007779{
Victor Stinner8c62be82010-05-06 00:08:46 +00007780 int fd, size;
7781 Py_ssize_t n;
7782 PyObject *buffer;
7783 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7784 return NULL;
7785 if (size < 0) {
7786 errno = EINVAL;
7787 return posix_error();
7788 }
7789 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7790 if (buffer == NULL)
7791 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007792 if (!_PyVerify_fd(fd)) {
7793 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007795 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 Py_BEGIN_ALLOW_THREADS
7797 n = read(fd, PyBytes_AS_STRING(buffer), size);
7798 Py_END_ALLOW_THREADS
7799 if (n < 0) {
7800 Py_DECREF(buffer);
7801 return posix_error();
7802 }
7803 if (n != size)
7804 _PyBytes_Resize(&buffer, n);
7805 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007806}
7807
Ross Lagerwall7807c352011-03-17 20:20:30 +02007808#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7809 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007810static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007811iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7812{
7813 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007814 Py_ssize_t blen, total = 0;
7815
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007816 *iov = PyMem_New(struct iovec, cnt);
7817 if (*iov == NULL) {
7818 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007819 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007820 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007821
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007822 *buf = PyMem_New(Py_buffer, cnt);
7823 if (*buf == NULL) {
7824 PyMem_Del(*iov);
7825 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007826 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007827 }
7828
7829 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007830 PyObject *item = PySequence_GetItem(seq, i);
7831 if (item == NULL)
7832 goto fail;
7833 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7834 Py_DECREF(item);
7835 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007836 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007837 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007838 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007839 blen = (*buf)[i].len;
7840 (*iov)[i].iov_len = blen;
7841 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007842 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007843 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007844
7845fail:
7846 PyMem_Del(*iov);
7847 for (j = 0; j < i; j++) {
7848 PyBuffer_Release(&(*buf)[j]);
7849 }
7850 PyMem_Del(*buf);
7851 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007852}
7853
7854static void
7855iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7856{
7857 int i;
7858 PyMem_Del(iov);
7859 for (i = 0; i < cnt; i++) {
7860 PyBuffer_Release(&buf[i]);
7861 }
7862 PyMem_Del(buf);
7863}
7864#endif
7865
Ross Lagerwall7807c352011-03-17 20:20:30 +02007866#ifdef HAVE_READV
7867PyDoc_STRVAR(posix_readv__doc__,
7868"readv(fd, buffers) -> bytesread\n\n\
7869Read from a file descriptor into a number of writable buffers. buffers\n\
7870is an arbitrary sequence of writable buffers.\n\
7871Returns the total number of bytes read.");
7872
7873static PyObject *
7874posix_readv(PyObject *self, PyObject *args)
7875{
7876 int fd, cnt;
7877 Py_ssize_t n;
7878 PyObject *seq;
7879 struct iovec *iov;
7880 Py_buffer *buf;
7881
7882 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7883 return NULL;
7884 if (!PySequence_Check(seq)) {
7885 PyErr_SetString(PyExc_TypeError,
7886 "readv() arg 2 must be a sequence");
7887 return NULL;
7888 }
7889 cnt = PySequence_Size(seq);
7890
7891 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7892 return NULL;
7893
7894 Py_BEGIN_ALLOW_THREADS
7895 n = readv(fd, iov, cnt);
7896 Py_END_ALLOW_THREADS
7897
7898 iov_cleanup(iov, buf, cnt);
7899 return PyLong_FromSsize_t(n);
7900}
7901#endif
7902
7903#ifdef HAVE_PREAD
7904PyDoc_STRVAR(posix_pread__doc__,
7905"pread(fd, buffersize, offset) -> string\n\n\
7906Read from a file descriptor, fd, at a position of offset. It will read up\n\
7907to buffersize number of bytes. The file offset remains unchanged.");
7908
7909static PyObject *
7910posix_pread(PyObject *self, PyObject *args)
7911{
7912 int fd, size;
7913 off_t offset;
7914 Py_ssize_t n;
7915 PyObject *buffer;
7916 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7917 return NULL;
7918
7919 if (size < 0) {
7920 errno = EINVAL;
7921 return posix_error();
7922 }
7923 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7924 if (buffer == NULL)
7925 return NULL;
7926 if (!_PyVerify_fd(fd)) {
7927 Py_DECREF(buffer);
7928 return posix_error();
7929 }
7930 Py_BEGIN_ALLOW_THREADS
7931 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7932 Py_END_ALLOW_THREADS
7933 if (n < 0) {
7934 Py_DECREF(buffer);
7935 return posix_error();
7936 }
7937 if (n != size)
7938 _PyBytes_Resize(&buffer, n);
7939 return buffer;
7940}
7941#endif
7942
7943PyDoc_STRVAR(posix_write__doc__,
7944"write(fd, string) -> byteswritten\n\n\
7945Write a string to a file descriptor.");
7946
7947static PyObject *
7948posix_write(PyObject *self, PyObject *args)
7949{
7950 Py_buffer pbuf;
7951 int fd;
7952 Py_ssize_t size, len;
7953
7954 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7955 return NULL;
7956 if (!_PyVerify_fd(fd)) {
7957 PyBuffer_Release(&pbuf);
7958 return posix_error();
7959 }
7960 len = pbuf.len;
7961 Py_BEGIN_ALLOW_THREADS
7962#if defined(MS_WIN64) || defined(MS_WINDOWS)
7963 if (len > INT_MAX)
7964 len = INT_MAX;
7965 size = write(fd, pbuf.buf, (int)len);
7966#else
7967 size = write(fd, pbuf.buf, len);
7968#endif
7969 Py_END_ALLOW_THREADS
7970 PyBuffer_Release(&pbuf);
7971 if (size < 0)
7972 return posix_error();
7973 return PyLong_FromSsize_t(size);
7974}
7975
7976#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007977PyDoc_STRVAR(posix_sendfile__doc__,
7978"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7979sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7980 -> byteswritten\n\
7981Copy nbytes bytes from file descriptor in to file descriptor out.");
7982
7983static PyObject *
7984posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7985{
7986 int in, out;
7987 Py_ssize_t ret;
7988 off_t offset;
7989
7990#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7991#ifndef __APPLE__
7992 Py_ssize_t len;
7993#endif
7994 PyObject *headers = NULL, *trailers = NULL;
7995 Py_buffer *hbuf, *tbuf;
7996 off_t sbytes;
7997 struct sf_hdtr sf;
7998 int flags = 0;
7999 sf.headers = NULL;
8000 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008001 static char *keywords[] = {"out", "in",
8002 "offset", "count",
8003 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008004
8005#ifdef __APPLE__
8006 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008007 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008008#else
8009 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008010 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008011#endif
8012 &headers, &trailers, &flags))
8013 return NULL;
8014 if (headers != NULL) {
8015 if (!PySequence_Check(headers)) {
8016 PyErr_SetString(PyExc_TypeError,
8017 "sendfile() headers must be a sequence or None");
8018 return NULL;
8019 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008020 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008021 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008022 if (sf.hdr_cnt > 0 &&
8023 !(i = iov_setup(&(sf.headers), &hbuf,
8024 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008025 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008026#ifdef __APPLE__
8027 sbytes += i;
8028#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008029 }
8030 }
8031 if (trailers != NULL) {
8032 if (!PySequence_Check(trailers)) {
8033 PyErr_SetString(PyExc_TypeError,
8034 "sendfile() trailers must be a sequence or None");
8035 return NULL;
8036 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008037 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008038 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008039 if (sf.trl_cnt > 0 &&
8040 !(i = iov_setup(&(sf.trailers), &tbuf,
8041 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008042 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008043#ifdef __APPLE__
8044 sbytes += i;
8045#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008046 }
8047 }
8048
8049 Py_BEGIN_ALLOW_THREADS
8050#ifdef __APPLE__
8051 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8052#else
8053 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8054#endif
8055 Py_END_ALLOW_THREADS
8056
8057 if (sf.headers != NULL)
8058 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8059 if (sf.trailers != NULL)
8060 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8061
8062 if (ret < 0) {
8063 if ((errno == EAGAIN) || (errno == EBUSY)) {
8064 if (sbytes != 0) {
8065 // some data has been sent
8066 goto done;
8067 }
8068 else {
8069 // no data has been sent; upper application is supposed
8070 // to retry on EAGAIN or EBUSY
8071 return posix_error();
8072 }
8073 }
8074 return posix_error();
8075 }
8076 goto done;
8077
8078done:
8079 #if !defined(HAVE_LARGEFILE_SUPPORT)
8080 return Py_BuildValue("l", sbytes);
8081 #else
8082 return Py_BuildValue("L", sbytes);
8083 #endif
8084
8085#else
8086 Py_ssize_t count;
8087 PyObject *offobj;
8088 static char *keywords[] = {"out", "in",
8089 "offset", "count", NULL};
8090 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8091 keywords, &out, &in, &offobj, &count))
8092 return NULL;
8093#ifdef linux
8094 if (offobj == Py_None) {
8095 Py_BEGIN_ALLOW_THREADS
8096 ret = sendfile(out, in, NULL, count);
8097 Py_END_ALLOW_THREADS
8098 if (ret < 0)
8099 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008100 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008101 }
8102#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008103 if (!_parse_off_t(offobj, &offset))
8104 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008105 Py_BEGIN_ALLOW_THREADS
8106 ret = sendfile(out, in, &offset, count);
8107 Py_END_ALLOW_THREADS
8108 if (ret < 0)
8109 return posix_error();
8110 return Py_BuildValue("n", ret);
8111#endif
8112}
8113#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008114
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008115PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008116"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008117Like stat(), but for an open file descriptor.\n\
8118Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008119
Barry Warsaw53699e91996-12-10 23:23:01 +00008120static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008121posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008122{
Victor Stinner8c62be82010-05-06 00:08:46 +00008123 int fd;
8124 STRUCT_STAT st;
8125 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008126 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008128#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008129 /* on OpenVMS we must ensure that all bytes are written to the file */
8130 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008131#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 if (!_PyVerify_fd(fd))
8133 return posix_error();
8134 Py_BEGIN_ALLOW_THREADS
8135 res = FSTAT(fd, &st);
8136 Py_END_ALLOW_THREADS
8137 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008138#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008140#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008141 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008142#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008143 }
Tim Peters5aa91602002-01-30 05:46:57 +00008144
Victor Stinner4195b5c2012-02-08 23:03:19 +01008145 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008146}
8147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008148PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008149"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008150Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008151connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008152
8153static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008154posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008155{
Victor Stinner8c62be82010-05-06 00:08:46 +00008156 int fd;
8157 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8158 return NULL;
8159 if (!_PyVerify_fd(fd))
8160 return PyBool_FromLong(0);
8161 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008162}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008163
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008164#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008165PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008166"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008167Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008168
Barry Warsaw53699e91996-12-10 23:23:01 +00008169static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008170posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008171{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008172#if defined(PYOS_OS2)
8173 HFILE read, write;
8174 APIRET rc;
8175
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008176 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008177 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008178 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008179
8180 return Py_BuildValue("(ii)", read, write);
8181#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008182#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008183 int fds[2];
8184 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008185 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008186 if (res != 0)
8187 return posix_error();
8188 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008189#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 HANDLE read, write;
8191 int read_fd, write_fd;
8192 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 if (!ok)
8195 return win32_error("CreatePipe", NULL);
8196 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8197 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8198 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008199#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008200#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008201}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008202#endif /* HAVE_PIPE */
8203
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008204#ifdef HAVE_PIPE2
8205PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008206"pipe2(flags) -> (read_end, write_end)\n\n\
8207Create a pipe with flags set atomically.\n\
8208flags can be constructed by ORing together one or more of these values:\n\
8209O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008210");
8211
8212static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008213posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008214{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008215 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008216 int fds[2];
8217 int res;
8218
Charles-François Natali368f34b2011-06-06 19:49:47 +02008219 flags = PyLong_AsLong(arg);
8220 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008221 return NULL;
8222
8223 res = pipe2(fds, flags);
8224 if (res != 0)
8225 return posix_error();
8226 return Py_BuildValue("(ii)", fds[0], fds[1]);
8227}
8228#endif /* HAVE_PIPE2 */
8229
Ross Lagerwall7807c352011-03-17 20:20:30 +02008230#ifdef HAVE_WRITEV
8231PyDoc_STRVAR(posix_writev__doc__,
8232"writev(fd, buffers) -> byteswritten\n\n\
8233Write the contents of buffers to a file descriptor, where buffers is an\n\
8234arbitrary sequence of buffers.\n\
8235Returns the total bytes written.");
8236
8237static PyObject *
8238posix_writev(PyObject *self, PyObject *args)
8239{
8240 int fd, cnt;
8241 Py_ssize_t res;
8242 PyObject *seq;
8243 struct iovec *iov;
8244 Py_buffer *buf;
8245 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8246 return NULL;
8247 if (!PySequence_Check(seq)) {
8248 PyErr_SetString(PyExc_TypeError,
8249 "writev() arg 2 must be a sequence");
8250 return NULL;
8251 }
8252 cnt = PySequence_Size(seq);
8253
8254 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8255 return NULL;
8256 }
8257
8258 Py_BEGIN_ALLOW_THREADS
8259 res = writev(fd, iov, cnt);
8260 Py_END_ALLOW_THREADS
8261
8262 iov_cleanup(iov, buf, cnt);
8263 return PyLong_FromSsize_t(res);
8264}
8265#endif
8266
8267#ifdef HAVE_PWRITE
8268PyDoc_STRVAR(posix_pwrite__doc__,
8269"pwrite(fd, string, offset) -> byteswritten\n\n\
8270Write string to a file descriptor, fd, from offset, leaving the file\n\
8271offset unchanged.");
8272
8273static PyObject *
8274posix_pwrite(PyObject *self, PyObject *args)
8275{
8276 Py_buffer pbuf;
8277 int fd;
8278 off_t offset;
8279 Py_ssize_t size;
8280
8281 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8282 return NULL;
8283
8284 if (!_PyVerify_fd(fd)) {
8285 PyBuffer_Release(&pbuf);
8286 return posix_error();
8287 }
8288 Py_BEGIN_ALLOW_THREADS
8289 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8290 Py_END_ALLOW_THREADS
8291 PyBuffer_Release(&pbuf);
8292 if (size < 0)
8293 return posix_error();
8294 return PyLong_FromSsize_t(size);
8295}
8296#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008297
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008298#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008299PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008300"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8301Create a FIFO (a POSIX named pipe).\n\
8302\n\
8303If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8304 and path should be relative; path will then be relative to that directory.\n\
8305dir_fd may not be implemented on your platform.\n\
8306 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008307
Barry Warsaw53699e91996-12-10 23:23:01 +00008308static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008309posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008310{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008311 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008312 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008313 int dir_fd = DEFAULT_DIR_FD;
8314 int result;
8315 PyObject *return_value = NULL;
8316 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8317
8318 memset(&path, 0, sizeof(path));
8319 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8320 path_converter, &path,
8321 &mode,
8322#ifdef HAVE_MKFIFOAT
8323 dir_fd_converter, &dir_fd
8324#else
8325 dir_fd_unavailable, &dir_fd
8326#endif
8327 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008328 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008329
Victor Stinner8c62be82010-05-06 00:08:46 +00008330 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008331#ifdef HAVE_MKFIFOAT
8332 if (dir_fd != DEFAULT_DIR_FD)
8333 result = mkfifoat(dir_fd, path.narrow, mode);
8334 else
8335#endif
8336 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008337 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008338
8339 if (result < 0) {
8340 return_value = posix_error();
8341 goto exit;
8342 }
8343
8344 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008345 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008346
8347exit:
8348 path_cleanup(&path);
8349 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008350}
8351#endif
8352
Neal Norwitz11690112002-07-30 01:08:28 +00008353#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008354PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008355"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008356Create a filesystem node (file, device special file or named pipe)\n\
8357named filename. mode specifies both the permissions to use and the\n\
8358type of node to be created, being combined (bitwise OR) with one of\n\
8359S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008360device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008361os.makedev()), otherwise it is ignored.\n\
8362\n\
8363If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8364 and path should be relative; path will then be relative to that directory.\n\
8365dir_fd may not be implemented on your platform.\n\
8366 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008367
8368
8369static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008370posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008371{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008372 path_t path;
8373 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008375 int dir_fd = DEFAULT_DIR_FD;
8376 int result;
8377 PyObject *return_value = NULL;
8378 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8379
8380 memset(&path, 0, sizeof(path));
8381 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8382 path_converter, &path,
8383 &mode, &device,
8384#ifdef HAVE_MKNODAT
8385 dir_fd_converter, &dir_fd
8386#else
8387 dir_fd_unavailable, &dir_fd
8388#endif
8389 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008390 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008391
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008393#ifdef HAVE_MKNODAT
8394 if (dir_fd != DEFAULT_DIR_FD)
8395 result = mknodat(dir_fd, path.narrow, mode, device);
8396 else
8397#endif
8398 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008399 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008400
8401 if (result < 0) {
8402 return_value = posix_error();
8403 goto exit;
8404 }
8405
8406 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008407 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008408
8409exit:
8410 path_cleanup(&path);
8411 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008412}
8413#endif
8414
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008415#ifdef HAVE_DEVICE_MACROS
8416PyDoc_STRVAR(posix_major__doc__,
8417"major(device) -> major number\n\
8418Extracts a device major number from a raw device number.");
8419
8420static PyObject *
8421posix_major(PyObject *self, PyObject *args)
8422{
Victor Stinner8c62be82010-05-06 00:08:46 +00008423 int device;
8424 if (!PyArg_ParseTuple(args, "i:major", &device))
8425 return NULL;
8426 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008427}
8428
8429PyDoc_STRVAR(posix_minor__doc__,
8430"minor(device) -> minor number\n\
8431Extracts a device minor number from a raw device number.");
8432
8433static PyObject *
8434posix_minor(PyObject *self, PyObject *args)
8435{
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 int device;
8437 if (!PyArg_ParseTuple(args, "i:minor", &device))
8438 return NULL;
8439 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008440}
8441
8442PyDoc_STRVAR(posix_makedev__doc__,
8443"makedev(major, minor) -> device number\n\
8444Composes a raw device number from the major and minor device numbers.");
8445
8446static PyObject *
8447posix_makedev(PyObject *self, PyObject *args)
8448{
Victor Stinner8c62be82010-05-06 00:08:46 +00008449 int major, minor;
8450 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8451 return NULL;
8452 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008453}
8454#endif /* device macros */
8455
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008456
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008457#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008458PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008459"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008460Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008461
Barry Warsaw53699e91996-12-10 23:23:01 +00008462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008463posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008464{
Victor Stinner8c62be82010-05-06 00:08:46 +00008465 int fd;
8466 off_t length;
8467 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008468
Ross Lagerwall7807c352011-03-17 20:20:30 +02008469 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008470 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008471
Victor Stinner8c62be82010-05-06 00:08:46 +00008472 Py_BEGIN_ALLOW_THREADS
8473 res = ftruncate(fd, length);
8474 Py_END_ALLOW_THREADS
8475 if (res < 0)
8476 return posix_error();
8477 Py_INCREF(Py_None);
8478 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008479}
8480#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008481
Ross Lagerwall7807c352011-03-17 20:20:30 +02008482#ifdef HAVE_TRUNCATE
8483PyDoc_STRVAR(posix_truncate__doc__,
8484"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008485Truncate the file given by path to length bytes.\n\
8486On some platforms, path may also be specified as an open file descriptor.\n\
8487 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008488
8489static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008490posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008491{
Georg Brandl306336b2012-06-24 12:55:33 +02008492 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008493 off_t length;
8494 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008495 PyObject *result = NULL;
8496 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008497
Georg Brandl306336b2012-06-24 12:55:33 +02008498 memset(&path, 0, sizeof(path));
8499#ifdef HAVE_FTRUNCATE
8500 path.allow_fd = 1;
8501#endif
8502 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8503 path_converter, &path,
8504 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008505 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008506
8507 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008508#ifdef HAVE_FTRUNCATE
8509 if (path.fd != -1)
8510 res = ftruncate(path.fd, length);
8511 else
8512#endif
8513 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008514 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008515 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008516 result = path_posix_error("truncate", &path);
8517 else {
8518 Py_INCREF(Py_None);
8519 result = Py_None;
8520 }
8521 path_cleanup(&path);
8522 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008523}
8524#endif
8525
8526#ifdef HAVE_POSIX_FALLOCATE
8527PyDoc_STRVAR(posix_posix_fallocate__doc__,
8528"posix_fallocate(fd, offset, len)\n\n\
8529Ensures that enough disk space is allocated for the file specified by fd\n\
8530starting from offset and continuing for len bytes.");
8531
8532static PyObject *
8533posix_posix_fallocate(PyObject *self, PyObject *args)
8534{
8535 off_t len, offset;
8536 int res, fd;
8537
8538 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8539 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8540 return NULL;
8541
8542 Py_BEGIN_ALLOW_THREADS
8543 res = posix_fallocate(fd, offset, len);
8544 Py_END_ALLOW_THREADS
8545 if (res != 0) {
8546 errno = res;
8547 return posix_error();
8548 }
8549 Py_RETURN_NONE;
8550}
8551#endif
8552
8553#ifdef HAVE_POSIX_FADVISE
8554PyDoc_STRVAR(posix_posix_fadvise__doc__,
8555"posix_fadvise(fd, offset, len, advice)\n\n\
8556Announces an intention to access data in a specific pattern thus allowing\n\
8557the kernel to make optimizations.\n\
8558The advice applies to the region of the file specified by fd starting at\n\
8559offset and continuing for len bytes.\n\
8560advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8561POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8562POSIX_FADV_DONTNEED.");
8563
8564static PyObject *
8565posix_posix_fadvise(PyObject *self, PyObject *args)
8566{
8567 off_t len, offset;
8568 int res, fd, advice;
8569
8570 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8571 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8572 return NULL;
8573
8574 Py_BEGIN_ALLOW_THREADS
8575 res = posix_fadvise(fd, offset, len, advice);
8576 Py_END_ALLOW_THREADS
8577 if (res != 0) {
8578 errno = res;
8579 return posix_error();
8580 }
8581 Py_RETURN_NONE;
8582}
8583#endif
8584
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008585#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008586PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008587"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008588Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008589
Fred Drake762e2061999-08-26 17:23:54 +00008590/* Save putenv() parameters as values here, so we can collect them when they
8591 * get re-set with another call for the same key. */
8592static PyObject *posix_putenv_garbage;
8593
Tim Peters5aa91602002-01-30 05:46:57 +00008594static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008595posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008596{
Victor Stinner84ae1182010-05-06 22:05:07 +00008597 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008598#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008599 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008600 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008601
Victor Stinner8c62be82010-05-06 00:08:46 +00008602 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008603 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008604 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008605 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008606
Victor Stinner65170952011-11-22 22:16:17 +01008607 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008608 if (newstr == NULL) {
8609 PyErr_NoMemory();
8610 goto error;
8611 }
Victor Stinner65170952011-11-22 22:16:17 +01008612 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8613 PyErr_Format(PyExc_ValueError,
8614 "the environment variable is longer than %u characters",
8615 _MAX_ENV);
8616 goto error;
8617 }
8618
Victor Stinner8c62be82010-05-06 00:08:46 +00008619 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008620 if (newenv == NULL)
8621 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008622 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008623 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008624 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008625 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008626#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008627 PyObject *os1, *os2;
8628 char *s1, *s2;
8629 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008630
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008631 if (!PyArg_ParseTuple(args,
8632 "O&O&:putenv",
8633 PyUnicode_FSConverter, &os1,
8634 PyUnicode_FSConverter, &os2))
8635 return NULL;
8636 s1 = PyBytes_AsString(os1);
8637 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008638
Victor Stinner65170952011-11-22 22:16:17 +01008639 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008640 if (newstr == NULL) {
8641 PyErr_NoMemory();
8642 goto error;
8643 }
8644
Victor Stinner8c62be82010-05-06 00:08:46 +00008645 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008646 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008647 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008648 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008649 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008650#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008651
Victor Stinner8c62be82010-05-06 00:08:46 +00008652 /* Install the first arg and newstr in posix_putenv_garbage;
8653 * this will cause previous value to be collected. This has to
8654 * happen after the real putenv() call because the old value
8655 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008656 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008657 /* really not much we can do; just leak */
8658 PyErr_Clear();
8659 }
8660 else {
8661 Py_DECREF(newstr);
8662 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008663
Martin v. Löwis011e8422009-05-05 04:43:17 +00008664#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008665 Py_DECREF(os1);
8666 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008667#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008668 Py_RETURN_NONE;
8669
8670error:
8671#ifndef MS_WINDOWS
8672 Py_DECREF(os1);
8673 Py_DECREF(os2);
8674#endif
8675 Py_XDECREF(newstr);
8676 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008677}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008678#endif /* putenv */
8679
Guido van Rossumc524d952001-10-19 01:31:59 +00008680#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008681PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008682"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008683Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008684
8685static PyObject *
8686posix_unsetenv(PyObject *self, PyObject *args)
8687{
Victor Stinner65170952011-11-22 22:16:17 +01008688 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008689#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008690 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008691#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008692
8693 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008694
Victor Stinner65170952011-11-22 22:16:17 +01008695 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008696 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008697
Victor Stinner984890f2011-11-24 13:53:38 +01008698#ifdef HAVE_BROKEN_UNSETENV
8699 unsetenv(PyBytes_AS_STRING(name));
8700#else
Victor Stinner65170952011-11-22 22:16:17 +01008701 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008702 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008703 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008704 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008705 }
Victor Stinner984890f2011-11-24 13:53:38 +01008706#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008707
Victor Stinner8c62be82010-05-06 00:08:46 +00008708 /* Remove the key from posix_putenv_garbage;
8709 * this will cause it to be collected. This has to
8710 * happen after the real unsetenv() call because the
8711 * old value was still accessible until then.
8712 */
Victor Stinner65170952011-11-22 22:16:17 +01008713 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008714 /* really not much we can do; just leak */
8715 PyErr_Clear();
8716 }
Victor Stinner65170952011-11-22 22:16:17 +01008717 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008718 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008719}
8720#endif /* unsetenv */
8721
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008722PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008723"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008724Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008725
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008727posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008728{
Victor Stinner8c62be82010-05-06 00:08:46 +00008729 int code;
8730 char *message;
8731 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8732 return NULL;
8733 message = strerror(code);
8734 if (message == NULL) {
8735 PyErr_SetString(PyExc_ValueError,
8736 "strerror() argument out of range");
8737 return NULL;
8738 }
Victor Stinner1b579672011-12-17 05:47:23 +01008739 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008740}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008741
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008742
Guido van Rossumc9641791998-08-04 15:26:23 +00008743#ifdef HAVE_SYS_WAIT_H
8744
Fred Drake106c1a02002-04-23 15:58:02 +00008745#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008746PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008747"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008748Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008749
8750static PyObject *
8751posix_WCOREDUMP(PyObject *self, PyObject *args)
8752{
Victor Stinner8c62be82010-05-06 00:08:46 +00008753 WAIT_TYPE status;
8754 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008755
Victor Stinner8c62be82010-05-06 00:08:46 +00008756 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8757 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008758
Victor Stinner8c62be82010-05-06 00:08:46 +00008759 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008760}
8761#endif /* WCOREDUMP */
8762
8763#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008764PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008765"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008766Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008767job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008768
8769static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008770posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008771{
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 WAIT_TYPE status;
8773 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008774
Victor Stinner8c62be82010-05-06 00:08:46 +00008775 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8776 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008777
Victor Stinner8c62be82010-05-06 00:08:46 +00008778 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008779}
8780#endif /* WIFCONTINUED */
8781
Guido van Rossumc9641791998-08-04 15:26:23 +00008782#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008783PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008784"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008785Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008786
8787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008788posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008789{
Victor Stinner8c62be82010-05-06 00:08:46 +00008790 WAIT_TYPE status;
8791 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008792
Victor Stinner8c62be82010-05-06 00:08:46 +00008793 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8794 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008795
Victor Stinner8c62be82010-05-06 00:08:46 +00008796 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008797}
8798#endif /* WIFSTOPPED */
8799
8800#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008801PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008802"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008803Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008804
8805static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008806posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008807{
Victor Stinner8c62be82010-05-06 00:08:46 +00008808 WAIT_TYPE status;
8809 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008810
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8812 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008813
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008815}
8816#endif /* WIFSIGNALED */
8817
8818#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008819PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008820"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008821Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008822system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008823
8824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008825posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008826{
Victor Stinner8c62be82010-05-06 00:08:46 +00008827 WAIT_TYPE status;
8828 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008829
Victor Stinner8c62be82010-05-06 00:08:46 +00008830 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8831 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008832
Victor Stinner8c62be82010-05-06 00:08:46 +00008833 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008834}
8835#endif /* WIFEXITED */
8836
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008837#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008838PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008839"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008840Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008841
8842static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008843posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008844{
Victor Stinner8c62be82010-05-06 00:08:46 +00008845 WAIT_TYPE status;
8846 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008847
Victor Stinner8c62be82010-05-06 00:08:46 +00008848 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8849 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008850
Victor Stinner8c62be82010-05-06 00:08:46 +00008851 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008852}
8853#endif /* WEXITSTATUS */
8854
8855#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008856PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008857"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008858Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008859value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008860
8861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008862posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008863{
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 WAIT_TYPE status;
8865 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008866
Victor Stinner8c62be82010-05-06 00:08:46 +00008867 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8868 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008869
Victor Stinner8c62be82010-05-06 00:08:46 +00008870 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008871}
8872#endif /* WTERMSIG */
8873
8874#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008875PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008876"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008877Return the signal that stopped the process that provided\n\
8878the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008879
8880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008881posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008882{
Victor Stinner8c62be82010-05-06 00:08:46 +00008883 WAIT_TYPE status;
8884 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008885
Victor Stinner8c62be82010-05-06 00:08:46 +00008886 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8887 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008888
Victor Stinner8c62be82010-05-06 00:08:46 +00008889 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008890}
8891#endif /* WSTOPSIG */
8892
8893#endif /* HAVE_SYS_WAIT_H */
8894
8895
Thomas Wouters477c8d52006-05-27 19:21:47 +00008896#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008897#ifdef _SCO_DS
8898/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8899 needed definitions in sys/statvfs.h */
8900#define _SVID3
8901#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008902#include <sys/statvfs.h>
8903
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008904static PyObject*
8905_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008906 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8907 if (v == NULL)
8908 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008909
8910#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008911 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8912 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8913 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8914 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8915 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8916 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8917 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8918 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8919 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8920 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008921#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008922 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8923 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8924 PyStructSequence_SET_ITEM(v, 2,
8925 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8926 PyStructSequence_SET_ITEM(v, 3,
8927 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8928 PyStructSequence_SET_ITEM(v, 4,
8929 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8930 PyStructSequence_SET_ITEM(v, 5,
8931 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8932 PyStructSequence_SET_ITEM(v, 6,
8933 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8934 PyStructSequence_SET_ITEM(v, 7,
8935 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8936 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8937 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008938#endif
8939
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008941}
8942
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008943PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008944"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008945Perform an fstatvfs system call on the given fd.\n\
8946Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008947
8948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008949posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008950{
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 int fd, res;
8952 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008953
Victor Stinner8c62be82010-05-06 00:08:46 +00008954 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8955 return NULL;
8956 Py_BEGIN_ALLOW_THREADS
8957 res = fstatvfs(fd, &st);
8958 Py_END_ALLOW_THREADS
8959 if (res != 0)
8960 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008961
Victor Stinner8c62be82010-05-06 00:08:46 +00008962 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008963}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008964#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008965
8966
Thomas Wouters477c8d52006-05-27 19:21:47 +00008967#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008968#include <sys/statvfs.h>
8969
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008970PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008971"statvfs(path)\n\n\
8972Perform a statvfs system call on the given path.\n\
8973\n\
8974path may always be specified as a string.\n\
8975On some platforms, path may also be specified as an open file descriptor.\n\
8976 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008977
8978static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008979posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008980{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008981 static char *keywords[] = {"path", NULL};
8982 path_t path;
8983 int result;
8984 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008985 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008986
Larry Hastings9cf065c2012-06-22 16:30:09 -07008987 memset(&path, 0, sizeof(path));
8988#ifdef HAVE_FSTATVFS
8989 path.allow_fd = 1;
8990#endif
8991 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8992 path_converter, &path
8993 ))
8994 return NULL;
8995
8996 Py_BEGIN_ALLOW_THREADS
8997#ifdef HAVE_FSTATVFS
8998 if (path.fd != -1) {
8999#ifdef __APPLE__
9000 /* handle weak-linking on Mac OS X 10.3 */
9001 if (fstatvfs == NULL) {
9002 fd_specified("statvfs", path.fd);
9003 goto exit;
9004 }
9005#endif
9006 result = fstatvfs(path.fd, &st);
9007 }
9008 else
9009#endif
9010 result = statvfs(path.narrow, &st);
9011 Py_END_ALLOW_THREADS
9012
9013 if (result) {
9014 return_value = path_posix_error("statvfs", &path);
9015 goto exit;
9016 }
9017
9018 return_value = _pystatvfs_fromstructstatvfs(st);
9019
9020exit:
9021 path_cleanup(&path);
9022 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009023}
9024#endif /* HAVE_STATVFS */
9025
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009026#ifdef MS_WINDOWS
9027PyDoc_STRVAR(win32__getdiskusage__doc__,
9028"_getdiskusage(path) -> (total, free)\n\n\
9029Return disk usage statistics about the given path as (total, free) tuple.");
9030
9031static PyObject *
9032win32__getdiskusage(PyObject *self, PyObject *args)
9033{
9034 BOOL retval;
9035 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009036 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009037
Victor Stinner6139c1b2011-11-09 22:14:14 +01009038 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009039 return NULL;
9040
9041 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009042 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009043 Py_END_ALLOW_THREADS
9044 if (retval == 0)
9045 return PyErr_SetFromWindowsErr(0);
9046
9047 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9048}
9049#endif
9050
9051
Fred Drakec9680921999-12-13 16:37:25 +00009052/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9053 * It maps strings representing configuration variable names to
9054 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009055 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009056 * rarely-used constants. There are three separate tables that use
9057 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009058 *
9059 * This code is always included, even if none of the interfaces that
9060 * need it are included. The #if hackery needed to avoid it would be
9061 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009062 */
9063struct constdef {
9064 char *name;
9065 long value;
9066};
9067
Fred Drake12c6e2d1999-12-14 21:25:03 +00009068static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009069conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009070 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009071{
Christian Heimes217cfd12007-12-02 14:31:20 +00009072 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009073 *valuep = PyLong_AS_LONG(arg);
9074 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009075 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009076 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009077 /* look up the value in the table using a binary search */
9078 size_t lo = 0;
9079 size_t mid;
9080 size_t hi = tablesize;
9081 int cmp;
9082 const char *confname;
9083 if (!PyUnicode_Check(arg)) {
9084 PyErr_SetString(PyExc_TypeError,
9085 "configuration names must be strings or integers");
9086 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009088 confname = _PyUnicode_AsString(arg);
9089 if (confname == NULL)
9090 return 0;
9091 while (lo < hi) {
9092 mid = (lo + hi) / 2;
9093 cmp = strcmp(confname, table[mid].name);
9094 if (cmp < 0)
9095 hi = mid;
9096 else if (cmp > 0)
9097 lo = mid + 1;
9098 else {
9099 *valuep = table[mid].value;
9100 return 1;
9101 }
9102 }
9103 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9104 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009106}
9107
9108
9109#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9110static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009111#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009112 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009113#endif
9114#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009115 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009116#endif
Fred Drakec9680921999-12-13 16:37:25 +00009117#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009118 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009119#endif
9120#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009121 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009122#endif
9123#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009125#endif
9126#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009127 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009128#endif
9129#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009130 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009131#endif
9132#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009133 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009134#endif
9135#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009136 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009137#endif
9138#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009139 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009140#endif
9141#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009142 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009143#endif
9144#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009145 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009146#endif
9147#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009148 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009149#endif
9150#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009151 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009152#endif
9153#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009154 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009155#endif
9156#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009157 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009158#endif
9159#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009161#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009162#ifdef _PC_ACL_ENABLED
9163 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9164#endif
9165#ifdef _PC_MIN_HOLE_SIZE
9166 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9167#endif
9168#ifdef _PC_ALLOC_SIZE_MIN
9169 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9170#endif
9171#ifdef _PC_REC_INCR_XFER_SIZE
9172 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9173#endif
9174#ifdef _PC_REC_MAX_XFER_SIZE
9175 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9176#endif
9177#ifdef _PC_REC_MIN_XFER_SIZE
9178 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9179#endif
9180#ifdef _PC_REC_XFER_ALIGN
9181 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9182#endif
9183#ifdef _PC_SYMLINK_MAX
9184 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9185#endif
9186#ifdef _PC_XATTR_ENABLED
9187 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9188#endif
9189#ifdef _PC_XATTR_EXISTS
9190 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9191#endif
9192#ifdef _PC_TIMESTAMP_RESOLUTION
9193 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9194#endif
Fred Drakec9680921999-12-13 16:37:25 +00009195};
9196
Fred Drakec9680921999-12-13 16:37:25 +00009197static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009198conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009199{
9200 return conv_confname(arg, valuep, posix_constants_pathconf,
9201 sizeof(posix_constants_pathconf)
9202 / sizeof(struct constdef));
9203}
9204#endif
9205
9206#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009207PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009208"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009209Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009210If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009211
9212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009213posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009214{
9215 PyObject *result = NULL;
9216 int name, fd;
9217
Fred Drake12c6e2d1999-12-14 21:25:03 +00009218 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9219 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009220 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009221
Stefan Krah0e803b32010-11-26 16:16:47 +00009222 errno = 0;
9223 limit = fpathconf(fd, name);
9224 if (limit == -1 && errno != 0)
9225 posix_error();
9226 else
9227 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009228 }
9229 return result;
9230}
9231#endif
9232
9233
9234#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009235PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009236"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009237Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009238If there is no limit, return -1.\n\
9239On some platforms, path may also be specified as an open file descriptor.\n\
9240 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009241
9242static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009243posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009244{
Georg Brandl306336b2012-06-24 12:55:33 +02009245 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009246 PyObject *result = NULL;
9247 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009248 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009249
Georg Brandl306336b2012-06-24 12:55:33 +02009250 memset(&path, 0, sizeof(path));
9251#ifdef HAVE_FPATHCONF
9252 path.allow_fd = 1;
9253#endif
9254 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9255 path_converter, &path,
9256 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009258
Victor Stinner8c62be82010-05-06 00:08:46 +00009259 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009260#ifdef HAVE_FPATHCONF
9261 if (path.fd != -1)
9262 limit = fpathconf(path.fd, name);
9263 else
9264#endif
9265 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009266 if (limit == -1 && errno != 0) {
9267 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009268 /* could be a path or name problem */
9269 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009270 else
Georg Brandl306336b2012-06-24 12:55:33 +02009271 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009272 }
9273 else
9274 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009275 }
Georg Brandl306336b2012-06-24 12:55:33 +02009276 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009277 return result;
9278}
9279#endif
9280
9281#ifdef HAVE_CONFSTR
9282static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009283#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009284 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009285#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009286#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009287 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009288#endif
9289#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009290 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009291#endif
Fred Draked86ed291999-12-15 15:34:33 +00009292#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009293 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009294#endif
9295#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009296 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009297#endif
9298#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009299 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009300#endif
9301#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009302 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009303#endif
Fred Drakec9680921999-12-13 16:37:25 +00009304#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009306#endif
9307#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009309#endif
9310#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009312#endif
9313#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009315#endif
9316#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009318#endif
9319#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009321#endif
9322#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009324#endif
9325#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009327#endif
Fred Draked86ed291999-12-15 15:34:33 +00009328#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009330#endif
Fred Drakec9680921999-12-13 16:37:25 +00009331#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009333#endif
Fred Draked86ed291999-12-15 15:34:33 +00009334#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009336#endif
9337#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009339#endif
9340#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009342#endif
9343#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009345#endif
Fred Drakec9680921999-12-13 16:37:25 +00009346#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009348#endif
9349#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009351#endif
9352#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009354#endif
9355#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009357#endif
9358#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009360#endif
9361#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
9370#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009372#endif
9373#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009375#endif
9376#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009378#endif
9379#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009381#endif
9382#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009384#endif
9385#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009387#endif
9388#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009390#endif
9391#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009393#endif
Fred Draked86ed291999-12-15 15:34:33 +00009394#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009396#endif
9397#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009399#endif
9400#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009402#endif
9403#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009404 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009405#endif
9406#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009407 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009408#endif
9409#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009410 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009411#endif
9412#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009413 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009414#endif
9415#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009416 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009417#endif
9418#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009419 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009420#endif
9421#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009422 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009423#endif
9424#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009425 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009426#endif
9427#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009428 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009429#endif
9430#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009431 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009432#endif
Fred Drakec9680921999-12-13 16:37:25 +00009433};
9434
9435static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009436conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009437{
9438 return conv_confname(arg, valuep, posix_constants_confstr,
9439 sizeof(posix_constants_confstr)
9440 / sizeof(struct constdef));
9441}
9442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009443PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009444"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009445Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009446
9447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009448posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009449{
9450 PyObject *result = NULL;
9451 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009452 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009453 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009454
Victor Stinnercb043522010-09-10 23:49:04 +00009455 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9456 return NULL;
9457
9458 errno = 0;
9459 len = confstr(name, buffer, sizeof(buffer));
9460 if (len == 0) {
9461 if (errno) {
9462 posix_error();
9463 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009464 }
9465 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009466 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009467 }
9468 }
Victor Stinnercb043522010-09-10 23:49:04 +00009469
9470 if ((unsigned int)len >= sizeof(buffer)) {
9471 char *buf = PyMem_Malloc(len);
9472 if (buf == NULL)
9473 return PyErr_NoMemory();
9474 confstr(name, buf, len);
9475 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9476 PyMem_Free(buf);
9477 }
9478 else
9479 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009480 return result;
9481}
9482#endif
9483
9484
9485#ifdef HAVE_SYSCONF
9486static struct constdef posix_constants_sysconf[] = {
9487#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009489#endif
9490#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009491 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009492#endif
9493#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009494 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009495#endif
9496#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009498#endif
9499#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009501#endif
9502#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009504#endif
9505#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009507#endif
9508#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009510#endif
9511#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009513#endif
9514#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009516#endif
Fred Draked86ed291999-12-15 15:34:33 +00009517#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009519#endif
9520#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009522#endif
Fred Drakec9680921999-12-13 16:37:25 +00009523#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009525#endif
Fred Drakec9680921999-12-13 16:37:25 +00009526#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009528#endif
9529#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009531#endif
9532#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009534#endif
9535#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009537#endif
9538#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009540#endif
Fred Draked86ed291999-12-15 15:34:33 +00009541#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009543#endif
Fred Drakec9680921999-12-13 16:37:25 +00009544#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009546#endif
9547#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
9556#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009558#endif
Fred Draked86ed291999-12-15 15:34:33 +00009559#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009561#endif
Fred Drakec9680921999-12-13 16:37:25 +00009562#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009564#endif
9565#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009567#endif
9568#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
9571#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009573#endif
9574#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009576#endif
9577#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009579#endif
9580#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009582#endif
9583#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009585#endif
9586#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009588#endif
9589#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009591#endif
9592#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009594#endif
9595#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009597#endif
9598#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009600#endif
9601#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009603#endif
9604#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009606#endif
9607#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009609#endif
9610#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009611 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009612#endif
9613#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009614 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009615#endif
9616#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009617 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009618#endif
9619#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009620 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009621#endif
9622#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009624#endif
9625#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009627#endif
9628#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009630#endif
Fred Draked86ed291999-12-15 15:34:33 +00009631#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009633#endif
Fred Drakec9680921999-12-13 16:37:25 +00009634#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009636#endif
9637#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009639#endif
9640#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009642#endif
Fred Draked86ed291999-12-15 15:34:33 +00009643#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009645#endif
Fred Drakec9680921999-12-13 16:37:25 +00009646#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009648#endif
Fred Draked86ed291999-12-15 15:34:33 +00009649#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009651#endif
9652#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009654#endif
Fred Drakec9680921999-12-13 16:37:25 +00009655#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009657#endif
9658#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009660#endif
9661#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009663#endif
9664#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009666#endif
Fred Draked86ed291999-12-15 15:34:33 +00009667#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009669#endif
Fred Drakec9680921999-12-13 16:37:25 +00009670#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009672#endif
9673#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009675#endif
9676#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009678#endif
9679#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009680 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009681#endif
9682#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009684#endif
9685#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009687#endif
9688#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009690#endif
Fred Draked86ed291999-12-15 15:34:33 +00009691#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009693#endif
Fred Drakec9680921999-12-13 16:37:25 +00009694#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009696#endif
9697#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009698 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009699#endif
Fred Draked86ed291999-12-15 15:34:33 +00009700#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009702#endif
Fred Drakec9680921999-12-13 16:37:25 +00009703#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009705#endif
9706#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009708#endif
9709#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009711#endif
9712#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009714#endif
9715#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009717#endif
9718#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009720#endif
9721#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009723#endif
9724#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009726#endif
9727#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009729#endif
Fred Draked86ed291999-12-15 15:34:33 +00009730#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009732#endif
9733#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009735#endif
Fred Drakec9680921999-12-13 16:37:25 +00009736#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
9745#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
9760#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
9763#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
9769#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
9778#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009780#endif
9781#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
9784#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
9787#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
9796#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
9799#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009801#endif
9802#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009804#endif
9805#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
9814#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
9817#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009819#endif
9820#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
9832#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009834#endif
9835#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009837#endif
9838#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009840#endif
Fred Draked86ed291999-12-15 15:34:33 +00009841#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009843#endif
Fred Drakec9680921999-12-13 16:37:25 +00009844#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009846#endif
9847#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009849#endif
9850#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009852#endif
9853#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009855#endif
9856#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009858#endif
9859#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009861#endif
9862#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
9868#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009870#endif
9871#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
9874#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009876#endif
9877#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009879#endif
9880#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
9886#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
9889#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009891#endif
9892#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
9895#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
9898#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
9907#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
9910#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
9913#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
9952#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
9964#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979};
9980
9981static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009982conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009983{
9984 return conv_confname(arg, valuep, posix_constants_sysconf,
9985 sizeof(posix_constants_sysconf)
9986 / sizeof(struct constdef));
9987}
9988
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009989PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009990"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009991Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009992
9993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009994posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009995{
9996 PyObject *result = NULL;
9997 int name;
9998
9999 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10000 int value;
10001
10002 errno = 0;
10003 value = sysconf(name);
10004 if (value == -1 && errno != 0)
10005 posix_error();
10006 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010007 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010008 }
10009 return result;
10010}
10011#endif
10012
10013
Fred Drakebec628d1999-12-15 18:31:10 +000010014/* This code is used to ensure that the tables of configuration value names
10015 * are in sorted order as required by conv_confname(), and also to build the
10016 * the exported dictionaries that are used to publish information about the
10017 * names available on the host platform.
10018 *
10019 * Sorting the table at runtime ensures that the table is properly ordered
10020 * when used, even for platforms we're not able to test on. It also makes
10021 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010022 */
Fred Drakebec628d1999-12-15 18:31:10 +000010023
10024static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010025cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010026{
10027 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010029 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010031
10032 return strcmp(c1->name, c2->name);
10033}
10034
10035static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010036setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010038{
Fred Drakebec628d1999-12-15 18:31:10 +000010039 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010040 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010041
10042 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10043 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010044 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010046
Barry Warsaw3155db32000-04-13 15:20:40 +000010047 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 PyObject *o = PyLong_FromLong(table[i].value);
10049 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10050 Py_XDECREF(o);
10051 Py_DECREF(d);
10052 return -1;
10053 }
10054 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010055 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010056 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010057}
10058
Fred Drakebec628d1999-12-15 18:31:10 +000010059/* Return -1 on failure, 0 on success. */
10060static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010061setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010062{
10063#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010064 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010065 sizeof(posix_constants_pathconf)
10066 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010067 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010068 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010069#endif
10070#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010071 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010072 sizeof(posix_constants_confstr)
10073 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010074 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010075 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010076#endif
10077#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010078 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010079 sizeof(posix_constants_sysconf)
10080 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010081 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010082 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010083#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010084 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010085}
Fred Draked86ed291999-12-15 15:34:33 +000010086
10087
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010088PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010089"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010090Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010091in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010092
10093static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010094posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010095{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010096 abort();
10097 /*NOTREACHED*/
10098 Py_FatalError("abort() called from Python code didn't abort!");
10099 return NULL;
10100}
Fred Drakebec628d1999-12-15 18:31:10 +000010101
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010102#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010103PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010104"startfile(filepath [, operation]) - Start a file with its associated\n\
10105application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010106\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010107When \"operation\" is not specified or \"open\", this acts like\n\
10108double-clicking the file in Explorer, or giving the file name as an\n\
10109argument to the DOS \"start\" command: the file is opened with whatever\n\
10110application (if any) its extension is associated.\n\
10111When another \"operation\" is given, it specifies what should be done with\n\
10112the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010113\n\
10114startfile returns as soon as the associated application is launched.\n\
10115There is no option to wait for the application to close, and no way\n\
10116to retrieve the application's exit status.\n\
10117\n\
10118The filepath is relative to the current directory. If you want to use\n\
10119an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010120the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010121
10122static PyObject *
10123win32_startfile(PyObject *self, PyObject *args)
10124{
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 PyObject *ofilepath;
10126 char *filepath;
10127 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010128 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010130
Victor Stinnereb5657a2011-09-30 01:44:27 +020010131 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 if (!PyArg_ParseTuple(args, "U|s:startfile",
10133 &unipath, &operation)) {
10134 PyErr_Clear();
10135 goto normal;
10136 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010137
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010139 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010141 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 PyErr_Clear();
10143 operation = NULL;
10144 goto normal;
10145 }
10146 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010147
Victor Stinnereb5657a2011-09-30 01:44:27 +020010148 wpath = PyUnicode_AsUnicode(unipath);
10149 if (wpath == NULL)
10150 goto normal;
10151 if (uoperation) {
10152 woperation = PyUnicode_AsUnicode(uoperation);
10153 if (woperation == NULL)
10154 goto normal;
10155 }
10156 else
10157 woperation = NULL;
10158
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010160 rc = ShellExecuteW((HWND)0, woperation, wpath,
10161 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 Py_END_ALLOW_THREADS
10163
Victor Stinnereb5657a2011-09-30 01:44:27 +020010164 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010166 win32_error_object("startfile", unipath);
10167 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 }
10169 Py_INCREF(Py_None);
10170 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010171
10172normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10174 PyUnicode_FSConverter, &ofilepath,
10175 &operation))
10176 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010177 if (win32_warn_bytes_api()) {
10178 Py_DECREF(ofilepath);
10179 return NULL;
10180 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 filepath = PyBytes_AsString(ofilepath);
10182 Py_BEGIN_ALLOW_THREADS
10183 rc = ShellExecute((HWND)0, operation, filepath,
10184 NULL, NULL, SW_SHOWNORMAL);
10185 Py_END_ALLOW_THREADS
10186 if (rc <= (HINSTANCE)32) {
10187 PyObject *errval = win32_error("startfile", filepath);
10188 Py_DECREF(ofilepath);
10189 return errval;
10190 }
10191 Py_DECREF(ofilepath);
10192 Py_INCREF(Py_None);
10193 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010194}
10195#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010196
Martin v. Löwis438b5342002-12-27 10:16:42 +000010197#ifdef HAVE_GETLOADAVG
10198PyDoc_STRVAR(posix_getloadavg__doc__,
10199"getloadavg() -> (float, float, float)\n\n\
10200Return the number of processes in the system run queue averaged over\n\
10201the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10202was unobtainable");
10203
10204static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010205posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010206{
10207 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010208 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010209 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10210 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010211 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010212 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010213}
10214#endif
10215
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010216PyDoc_STRVAR(device_encoding__doc__,
10217"device_encoding(fd) -> str\n\n\
10218Return a string describing the encoding of the device\n\
10219if the output is a terminal; else return None.");
10220
10221static PyObject *
10222device_encoding(PyObject *self, PyObject *args)
10223{
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010225
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10227 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010228
10229 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010230}
10231
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010232#ifdef __VMS
10233/* Use openssl random routine */
10234#include <openssl/rand.h>
10235PyDoc_STRVAR(vms_urandom__doc__,
10236"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +000010237Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010238
10239static PyObject*
10240vms_urandom(PyObject *self, PyObject *args)
10241{
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 int howMany;
10243 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010244
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 /* Read arguments */
10246 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
10247 return NULL;
10248 if (howMany < 0)
10249 return PyErr_Format(PyExc_ValueError,
10250 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010251
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 /* Allocate bytes */
10253 result = PyBytes_FromStringAndSize(NULL, howMany);
10254 if (result != NULL) {
10255 /* Get random data */
10256 if (RAND_pseudo_bytes((unsigned char*)
10257 PyBytes_AS_STRING(result),
10258 howMany) < 0) {
10259 Py_DECREF(result);
10260 return PyErr_Format(PyExc_ValueError,
10261 "RAND_pseudo_bytes");
10262 }
10263 }
10264 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010265}
10266#endif
10267
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010268#ifdef HAVE_SETRESUID
10269PyDoc_STRVAR(posix_setresuid__doc__,
10270"setresuid(ruid, euid, suid)\n\n\
10271Set the current process's real, effective, and saved user ids.");
10272
10273static PyObject*
10274posix_setresuid (PyObject *self, PyObject *args)
10275{
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 /* We assume uid_t is no larger than a long. */
10277 long ruid, euid, suid;
10278 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
10279 return NULL;
10280 if (setresuid(ruid, euid, suid) < 0)
10281 return posix_error();
10282 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010283}
10284#endif
10285
10286#ifdef HAVE_SETRESGID
10287PyDoc_STRVAR(posix_setresgid__doc__,
10288"setresgid(rgid, egid, sgid)\n\n\
10289Set the current process's real, effective, and saved group ids.");
10290
10291static PyObject*
10292posix_setresgid (PyObject *self, PyObject *args)
10293{
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 /* We assume uid_t is no larger than a long. */
10295 long rgid, egid, sgid;
10296 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
10297 return NULL;
10298 if (setresgid(rgid, egid, sgid) < 0)
10299 return posix_error();
10300 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010301}
10302#endif
10303
10304#ifdef HAVE_GETRESUID
10305PyDoc_STRVAR(posix_getresuid__doc__,
10306"getresuid() -> (ruid, euid, suid)\n\n\
10307Get tuple of the current process's real, effective, and saved user ids.");
10308
10309static PyObject*
10310posix_getresuid (PyObject *self, PyObject *noargs)
10311{
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 uid_t ruid, euid, suid;
10313 long l_ruid, l_euid, l_suid;
10314 if (getresuid(&ruid, &euid, &suid) < 0)
10315 return posix_error();
10316 /* Force the values into long's as we don't know the size of uid_t. */
10317 l_ruid = ruid;
10318 l_euid = euid;
10319 l_suid = suid;
10320 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010321}
10322#endif
10323
10324#ifdef HAVE_GETRESGID
10325PyDoc_STRVAR(posix_getresgid__doc__,
10326"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010327Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010328
10329static PyObject*
10330posix_getresgid (PyObject *self, PyObject *noargs)
10331{
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 uid_t rgid, egid, sgid;
10333 long l_rgid, l_egid, l_sgid;
10334 if (getresgid(&rgid, &egid, &sgid) < 0)
10335 return posix_error();
10336 /* Force the values into long's as we don't know the size of uid_t. */
10337 l_rgid = rgid;
10338 l_egid = egid;
10339 l_sgid = sgid;
10340 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010341}
10342#endif
10343
Benjamin Peterson9428d532011-09-14 11:45:52 -040010344#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010345
Benjamin Peterson799bd802011-08-31 22:15:17 -040010346PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010347"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10348Return the value of extended attribute attribute on path.\n\
10349\n\
10350path may be either a string or an open file descriptor.\n\
10351If follow_symlinks is False, and the last element of the path is a symbolic\n\
10352 link, getxattr will examine the symbolic link itself instead of the file\n\
10353 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010354
10355static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010356posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010357{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010358 path_t path;
10359 path_t attribute;
10360 int follow_symlinks = 1;
10361 PyObject *buffer = NULL;
10362 int i;
10363 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010364
Larry Hastings9cf065c2012-06-22 16:30:09 -070010365 memset(&path, 0, sizeof(path));
10366 memset(&attribute, 0, sizeof(attribute));
10367 path.allow_fd = 1;
10368 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10369 path_converter, &path,
10370 path_converter, &attribute,
10371 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010372 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010373
Larry Hastings9cf065c2012-06-22 16:30:09 -070010374 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10375 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010376
Larry Hastings9cf065c2012-06-22 16:30:09 -070010377 for (i = 0; ; i++) {
10378 void *ptr;
10379 ssize_t result;
10380 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10381 Py_ssize_t buffer_size = buffer_sizes[i];
10382 if (!buffer_size) {
10383 path_error("getxattr", &path);
10384 goto exit;
10385 }
10386 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10387 if (!buffer)
10388 goto exit;
10389 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010390
Larry Hastings9cf065c2012-06-22 16:30:09 -070010391 Py_BEGIN_ALLOW_THREADS;
10392 if (path.fd >= 0)
10393 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10394 else if (follow_symlinks)
10395 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10396 else
10397 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10398 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010399
Larry Hastings9cf065c2012-06-22 16:30:09 -070010400 if (result < 0) {
10401 Py_DECREF(buffer);
10402 buffer = NULL;
10403 if (errno == ERANGE)
10404 continue;
10405 path_error("getxattr", &path);
10406 goto exit;
10407 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010408
Larry Hastings9cf065c2012-06-22 16:30:09 -070010409 if (result != buffer_size) {
10410 /* Can only shrink. */
10411 _PyBytes_Resize(&buffer, result);
10412 }
10413 break;
10414 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010415
Larry Hastings9cf065c2012-06-22 16:30:09 -070010416exit:
10417 path_cleanup(&path);
10418 path_cleanup(&attribute);
10419 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010420}
10421
10422PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010423"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10424Set extended attribute attribute on path to value.\n\
10425path may be either a string or an open file descriptor.\n\
10426If follow_symlinks is False, and the last element of the path is a symbolic\n\
10427 link, setxattr will modify the symbolic link itself instead of the file\n\
10428 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010429
10430static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010431posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010432{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010433 path_t path;
10434 path_t attribute;
10435 Py_buffer value;
10436 int flags = 0;
10437 int follow_symlinks = 1;
10438 int result;
10439 PyObject *return_value = NULL;
10440 static char *keywords[] = {"path", "attribute", "value",
10441 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010442
Larry Hastings9cf065c2012-06-22 16:30:09 -070010443 memset(&path, 0, sizeof(path));
10444 path.allow_fd = 1;
10445 memset(&attribute, 0, sizeof(attribute));
10446 memset(&value, 0, sizeof(value));
10447 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10448 keywords,
10449 path_converter, &path,
10450 path_converter, &attribute,
10451 &value, &flags,
10452 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010453 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010454
10455 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10456 goto exit;
10457
Benjamin Peterson799bd802011-08-31 22:15:17 -040010458 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010459 if (path.fd > -1)
10460 result = fsetxattr(path.fd, attribute.narrow,
10461 value.buf, value.len, flags);
10462 else if (follow_symlinks)
10463 result = setxattr(path.narrow, attribute.narrow,
10464 value.buf, value.len, flags);
10465 else
10466 result = lsetxattr(path.narrow, attribute.narrow,
10467 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010468 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010469
Larry Hastings9cf065c2012-06-22 16:30:09 -070010470 if (result) {
10471 return_value = path_error("setxattr", &path);
10472 goto exit;
10473 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010474
Larry Hastings9cf065c2012-06-22 16:30:09 -070010475 return_value = Py_None;
10476 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010477
Larry Hastings9cf065c2012-06-22 16:30:09 -070010478exit:
10479 path_cleanup(&path);
10480 path_cleanup(&attribute);
10481 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010482
Larry Hastings9cf065c2012-06-22 16:30:09 -070010483 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010484}
10485
10486PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010487"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10488Remove extended attribute attribute on path.\n\
10489path may be either a string or an open file descriptor.\n\
10490If follow_symlinks is False, and the last element of the path is a symbolic\n\
10491 link, removexattr will modify the symbolic link itself instead of the file\n\
10492 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010493
10494static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010495posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010496{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010497 path_t path;
10498 path_t attribute;
10499 int follow_symlinks = 1;
10500 int result;
10501 PyObject *return_value = NULL;
10502 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010503
Larry Hastings9cf065c2012-06-22 16:30:09 -070010504 memset(&path, 0, sizeof(path));
10505 memset(&attribute, 0, sizeof(attribute));
10506 path.allow_fd = 1;
10507 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10508 keywords,
10509 path_converter, &path,
10510 path_converter, &attribute,
10511 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010512 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010513
10514 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10515 goto exit;
10516
Benjamin Peterson799bd802011-08-31 22:15:17 -040010517 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010518 if (path.fd > -1)
10519 result = fremovexattr(path.fd, attribute.narrow);
10520 else if (follow_symlinks)
10521 result = removexattr(path.narrow, attribute.narrow);
10522 else
10523 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010524 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010525
Larry Hastings9cf065c2012-06-22 16:30:09 -070010526 if (result) {
10527 return_value = path_error("removexattr", &path);
10528 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010529 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010530
Larry Hastings9cf065c2012-06-22 16:30:09 -070010531 return_value = Py_None;
10532 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010533
Larry Hastings9cf065c2012-06-22 16:30:09 -070010534exit:
10535 path_cleanup(&path);
10536 path_cleanup(&attribute);
10537
10538 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010539}
10540
10541PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010542"listxattr(path='.', *, follow_symlinks=True)\n\n\
10543Return a list of extended attributes on path.\n\
10544\n\
10545path may be either None, a string, or an open file descriptor.\n\
10546if path is None, listxattr will examine the current directory.\n\
10547If follow_symlinks is False, and the last element of the path is a symbolic\n\
10548 link, listxattr will examine the symbolic link itself instead of the file\n\
10549 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010550
10551static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010552posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010553{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010554 path_t path;
10555 int follow_symlinks = 1;
10556 Py_ssize_t i;
10557 PyObject *result = NULL;
10558 char *buffer = NULL;
10559 char *name;
10560 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010561
Larry Hastings9cf065c2012-06-22 16:30:09 -070010562 memset(&path, 0, sizeof(path));
10563 path.allow_fd = 1;
10564 path.fd = -1;
10565 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10566 path_converter, &path,
10567 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010568 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010569
Larry Hastings9cf065c2012-06-22 16:30:09 -070010570 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10571 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010572
Larry Hastings9cf065c2012-06-22 16:30:09 -070010573 name = path.narrow ? path.narrow : ".";
10574 for (i = 0; ; i++) {
10575 char *start, *trace, *end;
10576 ssize_t length;
10577 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10578 Py_ssize_t buffer_size = buffer_sizes[i];
10579 if (!buffer_size) {
10580 // ERANGE
10581 path_error("listxattr", &path);
10582 break;
10583 }
10584 buffer = PyMem_MALLOC(buffer_size);
10585 if (!buffer) {
10586 PyErr_NoMemory();
10587 break;
10588 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010589
Larry Hastings9cf065c2012-06-22 16:30:09 -070010590 Py_BEGIN_ALLOW_THREADS;
10591 if (path.fd > -1)
10592 length = flistxattr(path.fd, buffer, buffer_size);
10593 else if (follow_symlinks)
10594 length = listxattr(name, buffer, buffer_size);
10595 else
10596 length = llistxattr(name, buffer, buffer_size);
10597 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010598
Larry Hastings9cf065c2012-06-22 16:30:09 -070010599 if (length < 0) {
10600 if (errno == ERANGE)
10601 continue;
10602 path_error("listxattr", &path);
10603 break;
10604 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010605
Larry Hastings9cf065c2012-06-22 16:30:09 -070010606 result = PyList_New(0);
10607 if (!result) {
10608 goto exit;
10609 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010610
Larry Hastings9cf065c2012-06-22 16:30:09 -070010611 end = buffer + length;
10612 for (trace = start = buffer; trace != end; trace++) {
10613 if (!*trace) {
10614 int error;
10615 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10616 trace - start);
10617 if (!attribute) {
10618 Py_DECREF(result);
10619 result = NULL;
10620 goto exit;
10621 }
10622 error = PyList_Append(result, attribute);
10623 Py_DECREF(attribute);
10624 if (error) {
10625 Py_DECREF(result);
10626 result = NULL;
10627 goto exit;
10628 }
10629 start = trace + 1;
10630 }
10631 }
10632 break;
10633 }
10634exit:
10635 path_cleanup(&path);
10636 if (buffer)
10637 PyMem_FREE(buffer);
10638 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010639}
10640
Benjamin Peterson9428d532011-09-14 11:45:52 -040010641#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010642
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010643
Georg Brandl2fb477c2012-02-21 00:33:36 +010010644PyDoc_STRVAR(posix_urandom__doc__,
10645"urandom(n) -> str\n\n\
10646Return n random bytes suitable for cryptographic use.");
10647
10648static PyObject *
10649posix_urandom(PyObject *self, PyObject *args)
10650{
10651 Py_ssize_t size;
10652 PyObject *result;
10653 int ret;
10654
10655 /* Read arguments */
10656 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10657 return NULL;
10658 if (size < 0)
10659 return PyErr_Format(PyExc_ValueError,
10660 "negative argument not allowed");
10661 result = PyBytes_FromStringAndSize(NULL, size);
10662 if (result == NULL)
10663 return NULL;
10664
10665 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10666 PyBytes_GET_SIZE(result));
10667 if (ret == -1) {
10668 Py_DECREF(result);
10669 return NULL;
10670 }
10671 return result;
10672}
10673
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010674/* Terminal size querying */
10675
10676static PyTypeObject TerminalSizeType;
10677
10678PyDoc_STRVAR(TerminalSize_docstring,
10679 "A tuple of (columns, lines) for holding terminal window size");
10680
10681static PyStructSequence_Field TerminalSize_fields[] = {
10682 {"columns", "width of the terminal window in characters"},
10683 {"lines", "height of the terminal window in characters"},
10684 {NULL, NULL}
10685};
10686
10687static PyStructSequence_Desc TerminalSize_desc = {
10688 "os.terminal_size",
10689 TerminalSize_docstring,
10690 TerminalSize_fields,
10691 2,
10692};
10693
10694#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10695PyDoc_STRVAR(termsize__doc__,
10696 "Return the size of the terminal window as (columns, lines).\n" \
10697 "\n" \
10698 "The optional argument fd (default standard output) specifies\n" \
10699 "which file descriptor should be queried.\n" \
10700 "\n" \
10701 "If the file descriptor is not connected to a terminal, an OSError\n" \
10702 "is thrown.\n" \
10703 "\n" \
10704 "This function will only be defined if an implementation is\n" \
10705 "available for this system.\n" \
10706 "\n" \
10707 "shutil.get_terminal_size is the high-level function which should \n" \
10708 "normally be used, os.get_terminal_size is the low-level implementation.");
10709
10710static PyObject*
10711get_terminal_size(PyObject *self, PyObject *args)
10712{
10713 int columns, lines;
10714 PyObject *termsize;
10715
10716 int fd = fileno(stdout);
10717 /* Under some conditions stdout may not be connected and
10718 * fileno(stdout) may point to an invalid file descriptor. For example
10719 * GUI apps don't have valid standard streams by default.
10720 *
10721 * If this happens, and the optional fd argument is not present,
10722 * the ioctl below will fail returning EBADF. This is what we want.
10723 */
10724
10725 if (!PyArg_ParseTuple(args, "|i", &fd))
10726 return NULL;
10727
10728#ifdef TERMSIZE_USE_IOCTL
10729 {
10730 struct winsize w;
10731 if (ioctl(fd, TIOCGWINSZ, &w))
10732 return PyErr_SetFromErrno(PyExc_OSError);
10733 columns = w.ws_col;
10734 lines = w.ws_row;
10735 }
10736#endif /* TERMSIZE_USE_IOCTL */
10737
10738#ifdef TERMSIZE_USE_CONIO
10739 {
10740 DWORD nhandle;
10741 HANDLE handle;
10742 CONSOLE_SCREEN_BUFFER_INFO csbi;
10743 switch (fd) {
10744 case 0: nhandle = STD_INPUT_HANDLE;
10745 break;
10746 case 1: nhandle = STD_OUTPUT_HANDLE;
10747 break;
10748 case 2: nhandle = STD_ERROR_HANDLE;
10749 break;
10750 default:
10751 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10752 }
10753 handle = GetStdHandle(nhandle);
10754 if (handle == NULL)
10755 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10756 if (handle == INVALID_HANDLE_VALUE)
10757 return PyErr_SetFromWindowsErr(0);
10758
10759 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10760 return PyErr_SetFromWindowsErr(0);
10761
10762 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10763 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10764 }
10765#endif /* TERMSIZE_USE_CONIO */
10766
10767 termsize = PyStructSequence_New(&TerminalSizeType);
10768 if (termsize == NULL)
10769 return NULL;
10770 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10771 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10772 if (PyErr_Occurred()) {
10773 Py_DECREF(termsize);
10774 return NULL;
10775 }
10776 return termsize;
10777}
10778#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10779
10780
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010781static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 {"access", (PyCFunction)posix_access,
10783 METH_VARARGS | METH_KEYWORDS,
10784 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010785#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010786 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010787#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010788 {"chdir", (PyCFunction)posix_chdir,
10789 METH_VARARGS | METH_KEYWORDS,
10790 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010791#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010792 {"chflags", (PyCFunction)posix_chflags,
10793 METH_VARARGS | METH_KEYWORDS,
10794 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010795#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010796 {"chmod", (PyCFunction)posix_chmod,
10797 METH_VARARGS | METH_KEYWORDS,
10798 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010799#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010800 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010801#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010802#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010803 {"chown", (PyCFunction)posix_chown,
10804 METH_VARARGS | METH_KEYWORDS,
10805 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010806#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010807#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010809#endif /* HAVE_LCHMOD */
10810#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010812#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010813#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010815#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010816#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010818#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010819#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010821#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010822#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010824#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010825#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10827 METH_NOARGS, posix_getcwd__doc__},
10828 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10829 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010830#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010831#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10832 {"link", (PyCFunction)posix_link,
10833 METH_VARARGS | METH_KEYWORDS,
10834 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010835#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010836 {"listdir", (PyCFunction)posix_listdir,
10837 METH_VARARGS | METH_KEYWORDS,
10838 posix_listdir__doc__},
10839 {"lstat", (PyCFunction)posix_lstat,
10840 METH_VARARGS | METH_KEYWORDS,
10841 posix_lstat__doc__},
10842 {"mkdir", (PyCFunction)posix_mkdir,
10843 METH_VARARGS | METH_KEYWORDS,
10844 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010845#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010847#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010848#ifdef HAVE_GETPRIORITY
10849 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10850#endif /* HAVE_GETPRIORITY */
10851#ifdef HAVE_SETPRIORITY
10852 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10853#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010854#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010855 {"readlink", (PyCFunction)posix_readlink,
10856 METH_VARARGS | METH_KEYWORDS,
10857 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010858#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010859#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010860 {"readlink", (PyCFunction)win_readlink,
10861 METH_VARARGS | METH_KEYWORDS,
10862 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010863#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010864 {"rename", (PyCFunction)posix_rename,
10865 METH_VARARGS | METH_KEYWORDS,
10866 posix_rename__doc__},
10867 {"replace", (PyCFunction)posix_replace,
10868 METH_VARARGS | METH_KEYWORDS,
10869 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010870 {"rmdir", (PyCFunction)posix_rmdir,
10871 METH_VARARGS | METH_KEYWORDS,
10872 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010873 {"stat", (PyCFunction)posix_stat,
10874 METH_VARARGS | METH_KEYWORDS,
10875 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010877#if defined(HAVE_SYMLINK)
10878 {"symlink", (PyCFunction)posix_symlink,
10879 METH_VARARGS | METH_KEYWORDS,
10880 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010881#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010882#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010884#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010886#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010887 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010888#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010889 {"unlink", (PyCFunction)posix_unlink,
10890 METH_VARARGS | METH_KEYWORDS,
10891 posix_unlink__doc__},
10892 {"remove", (PyCFunction)posix_unlink,
10893 METH_VARARGS | METH_KEYWORDS,
10894 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010895 {"utime", (PyCFunction)posix_utime,
10896 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010897#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010899#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010901#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010903 {"execve", (PyCFunction)posix_execve,
10904 METH_VARARGS | METH_KEYWORDS,
10905 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010906#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010907#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010908 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10909 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010910#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010911 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10912 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010913#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010914#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010915#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010917#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010918#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010920#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010921#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010922#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010923 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10924 {"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 +020010925#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010926#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010927 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010928#endif
10929#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010930 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010931#endif
10932#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010933 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010934#endif
10935#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010936 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010937#endif
10938#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010939 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010940#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010941 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010942#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010943 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10944 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10945#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010946#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010947#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010948 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010949#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010950#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010951 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010952#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010953#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010954 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010955#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010956#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010958#endif /* HAVE_GETEUID */
10959#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010960 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010961#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010962#ifdef HAVE_GETGROUPLIST
10963 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10964#endif
Fred Drakec9680921999-12-13 16:37:25 +000010965#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010967#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010968 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010969#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010971#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010972#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010974#endif /* HAVE_GETPPID */
10975#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010977#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010978#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010980#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010981#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010983#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010984#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010985 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010986#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010987#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010988 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010989#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010990#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10992 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010993#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010994#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010996#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010997#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010999#endif /* HAVE_SETEUID */
11000#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011002#endif /* HAVE_SETEGID */
11003#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011005#endif /* HAVE_SETREUID */
11006#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011008#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011009#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011011#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011012#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011014#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011015#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011016 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011017#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011018#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011020#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011021#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011022 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011023#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011024#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011025 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011026#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011027#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011028 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011029#endif /* HAVE_WAIT3 */
11030#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011031 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011032#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011033#if defined(HAVE_WAITID) && !defined(__APPLE__)
11034 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11035#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011036#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011037 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011038#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011039#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011040 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011041#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011042#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011044#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011045#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011046 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011047#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011048#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011050#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011051#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011053#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011054 {"open", (PyCFunction)posix_open,\
11055 METH_VARARGS | METH_KEYWORDS,
11056 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011057 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11058 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11059 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11060 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
11061 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011062#ifdef HAVE_LOCKF
11063 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11064#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11066 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011067#ifdef HAVE_READV
11068 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11069#endif
11070#ifdef HAVE_PREAD
11071 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11072#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011073 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011074#ifdef HAVE_WRITEV
11075 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11076#endif
11077#ifdef HAVE_PWRITE
11078 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11079#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011080#ifdef HAVE_SENDFILE
11081 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11082 posix_sendfile__doc__},
11083#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011084 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011086#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011087 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011088#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011089#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011090 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011091#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011092#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011093 {"mkfifo", (PyCFunction)posix_mkfifo,
11094 METH_VARARGS | METH_KEYWORDS,
11095 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011096#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011097#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011098 {"mknod", (PyCFunction)posix_mknod,
11099 METH_VARARGS | METH_KEYWORDS,
11100 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011101#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011102#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011103 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11104 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11105 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011106#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011107#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011108 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011109#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011110#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011111 {"truncate", (PyCFunction)posix_truncate,
11112 METH_VARARGS | METH_KEYWORDS,
11113 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011114#endif
11115#ifdef HAVE_POSIX_FALLOCATE
11116 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11117#endif
11118#ifdef HAVE_POSIX_FADVISE
11119 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11120#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011121#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011123#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011124#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011126#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011128#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011129 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011130#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011131#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011133#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011134#ifdef HAVE_SYNC
11135 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11136#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011137#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011138 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011139#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011140#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011141#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011143#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011144#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011145 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011146#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011147#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011149#endif /* WIFSTOPPED */
11150#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011152#endif /* WIFSIGNALED */
11153#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011155#endif /* WIFEXITED */
11156#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011158#endif /* WEXITSTATUS */
11159#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011161#endif /* WTERMSIG */
11162#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011164#endif /* WSTOPSIG */
11165#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011166#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011168#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011169#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011170 {"statvfs", (PyCFunction)posix_statvfs,
11171 METH_VARARGS | METH_KEYWORDS,
11172 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011173#endif
Fred Drakec9680921999-12-13 16:37:25 +000011174#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011176#endif
11177#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011178 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011179#endif
11180#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011181 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011182#endif
11183#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011184 {"pathconf", (PyCFunction)posix_pathconf,
11185 METH_VARARGS | METH_KEYWORDS,
11186 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011187#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011189#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011191 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011192 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011193 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011194 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011195#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011196#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011197 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011198#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011199 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011200#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011201 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011202#endif
11203#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011204 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011205#endif
11206#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011207 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011208#endif
11209#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011210 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011211#endif
11212
Benjamin Peterson9428d532011-09-14 11:45:52 -040011213#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011214 {"setxattr", (PyCFunction)posix_setxattr,
11215 METH_VARARGS | METH_KEYWORDS,
11216 posix_setxattr__doc__},
11217 {"getxattr", (PyCFunction)posix_getxattr,
11218 METH_VARARGS | METH_KEYWORDS,
11219 posix_getxattr__doc__},
11220 {"removexattr", (PyCFunction)posix_removexattr,
11221 METH_VARARGS | METH_KEYWORDS,
11222 posix_removexattr__doc__},
11223 {"listxattr", (PyCFunction)posix_listxattr,
11224 METH_VARARGS | METH_KEYWORDS,
11225 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011226#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011227#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11228 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11229#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011231};
11232
11233
Barry Warsaw4a342091996-12-19 23:50:02 +000011234static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011235ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011236{
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011238}
11239
Guido van Rossumd48f2521997-12-05 22:19:34 +000011240#if defined(PYOS_OS2)
11241/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011242static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011243{
11244 APIRET rc;
11245 ULONG values[QSV_MAX+1];
11246 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011247 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011248
11249 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011250 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011251 Py_END_ALLOW_THREADS
11252
11253 if (rc != NO_ERROR) {
11254 os2_error(rc);
11255 return -1;
11256 }
11257
Fred Drake4d1e64b2002-04-15 19:40:07 +000011258 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11259 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11260 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11261 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11262 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11263 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11264 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011265
11266 switch (values[QSV_VERSION_MINOR]) {
11267 case 0: ver = "2.00"; break;
11268 case 10: ver = "2.10"; break;
11269 case 11: ver = "2.11"; break;
11270 case 30: ver = "3.00"; break;
11271 case 40: ver = "4.00"; break;
11272 case 50: ver = "5.00"; break;
11273 default:
Tim Peters885d4572001-11-28 20:27:42 +000011274 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011275 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011276 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011277 ver = &tmp[0];
11278 }
11279
11280 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011281 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011282 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011283
11284 /* Add Indicator of Which Drive was Used to Boot the System */
11285 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11286 tmp[1] = ':';
11287 tmp[2] = '\0';
11288
Fred Drake4d1e64b2002-04-15 19:40:07 +000011289 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011290}
11291#endif
11292
Brian Curtin52173d42010-12-02 18:29:18 +000011293#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011294static int
Brian Curtin52173d42010-12-02 18:29:18 +000011295enable_symlink()
11296{
11297 HANDLE tok;
11298 TOKEN_PRIVILEGES tok_priv;
11299 LUID luid;
11300 int meth_idx = 0;
11301
11302 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011303 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011304
11305 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011306 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011307
11308 tok_priv.PrivilegeCount = 1;
11309 tok_priv.Privileges[0].Luid = luid;
11310 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11311
11312 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11313 sizeof(TOKEN_PRIVILEGES),
11314 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011315 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011316
Brian Curtin3b4499c2010-12-28 14:31:47 +000011317 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11318 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011319}
11320#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11321
Barry Warsaw4a342091996-12-19 23:50:02 +000011322static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011323all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011324{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011325#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011327#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011328#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011330#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011331#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011332 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011333#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011334#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011335 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011336#endif
Fred Drakec9680921999-12-13 16:37:25 +000011337#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011338 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011339#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011340#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011342#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011343#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011344 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011345#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011346#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011347 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011348#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011349#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011350 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011351#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011352#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011354#endif
11355#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011356 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011357#endif
11358#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011360#endif
11361#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011362 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011363#endif
11364#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011365 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011366#endif
11367#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011368 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011369#endif
11370#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011372#endif
11373#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011374 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011375#endif
11376#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011377 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011378#endif
11379#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011380 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011381#endif
11382#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011383 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011384#endif
11385#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011386 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011387#endif
11388#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011389 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011390#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011391#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011392 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011393#endif
11394#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011395 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011396#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011397#ifdef O_XATTR
11398 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11399#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011400#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011401 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011402#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011403#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011404 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011405#endif
11406#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011407 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011408#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011409#ifdef O_EXEC
11410 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11411#endif
11412#ifdef O_SEARCH
11413 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11414#endif
11415#ifdef O_TTY_INIT
11416 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11417#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011418#ifdef PRIO_PROCESS
11419 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11420#endif
11421#ifdef PRIO_PGRP
11422 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11423#endif
11424#ifdef PRIO_USER
11425 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11426#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011427#ifdef O_CLOEXEC
11428 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11429#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011430#ifdef O_ACCMODE
11431 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11432#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011433
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011434
Jesus Cea94363612012-06-22 18:32:07 +020011435#ifdef SEEK_HOLE
11436 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11437#endif
11438#ifdef SEEK_DATA
11439 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11440#endif
11441
Tim Peters5aa91602002-01-30 05:46:57 +000011442/* MS Windows */
11443#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 /* Don't inherit in child processes. */
11445 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011446#endif
11447#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011448 /* Optimize for short life (keep in memory). */
11449 /* MS forgot to define this one with a non-underscore form too. */
11450 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011451#endif
11452#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011453 /* Automatically delete when last handle is closed. */
11454 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011455#endif
11456#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011457 /* Optimize for random access. */
11458 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011459#endif
11460#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011461 /* Optimize for sequential access. */
11462 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011463#endif
11464
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011465/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011466#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011467 /* Send a SIGIO signal whenever input or output
11468 becomes available on file descriptor */
11469 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011470#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011471#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 /* Direct disk access. */
11473 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011474#endif
11475#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011476 /* Must be a directory. */
11477 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011478#endif
11479#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 /* Do not follow links. */
11481 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011482#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011483#ifdef O_NOLINKS
11484 /* Fails if link count of the named file is greater than 1 */
11485 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11486#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011487#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011488 /* Do not update the access time. */
11489 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011490#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011491
Victor Stinner8c62be82010-05-06 00:08:46 +000011492 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011493#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011494 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011495#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011496#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011497 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011498#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011499#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011500 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011501#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011502#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011504#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011505#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011506 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011507#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011508#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011509 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011510#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011511#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011512 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011513#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011514#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011515 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011516#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011517#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011518 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011519#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011520#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011521 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011522#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011523#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011524 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011525#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011526#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011527 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011528#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011529#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011530 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011531#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011532#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011533 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011534#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011535#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011536 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011537#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011538#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011539 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011540#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011541#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011542 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011543#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011544
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011545 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011546#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011547 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011548#endif /* ST_RDONLY */
11549#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011550 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011551#endif /* ST_NOSUID */
11552
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011553 /* FreeBSD sendfile() constants */
11554#ifdef SF_NODISKIO
11555 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11556#endif
11557#ifdef SF_MNOWAIT
11558 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11559#endif
11560#ifdef SF_SYNC
11561 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11562#endif
11563
Ross Lagerwall7807c352011-03-17 20:20:30 +020011564 /* constants for posix_fadvise */
11565#ifdef POSIX_FADV_NORMAL
11566 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11567#endif
11568#ifdef POSIX_FADV_SEQUENTIAL
11569 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11570#endif
11571#ifdef POSIX_FADV_RANDOM
11572 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11573#endif
11574#ifdef POSIX_FADV_NOREUSE
11575 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11576#endif
11577#ifdef POSIX_FADV_WILLNEED
11578 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11579#endif
11580#ifdef POSIX_FADV_DONTNEED
11581 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11582#endif
11583
11584 /* constants for waitid */
11585#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11586 if (ins(d, "P_PID", (long)P_PID)) return -1;
11587 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11588 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11589#endif
11590#ifdef WEXITED
11591 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11592#endif
11593#ifdef WNOWAIT
11594 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11595#endif
11596#ifdef WSTOPPED
11597 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11598#endif
11599#ifdef CLD_EXITED
11600 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11601#endif
11602#ifdef CLD_DUMPED
11603 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11604#endif
11605#ifdef CLD_TRAPPED
11606 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11607#endif
11608#ifdef CLD_CONTINUED
11609 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11610#endif
11611
11612 /* constants for lockf */
11613#ifdef F_LOCK
11614 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11615#endif
11616#ifdef F_TLOCK
11617 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11618#endif
11619#ifdef F_ULOCK
11620 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11621#endif
11622#ifdef F_TEST
11623 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11624#endif
11625
Guido van Rossum246bc171999-02-01 23:54:31 +000011626#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011627#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011628 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11629 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11630 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11631 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11632 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11633 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11634 if (ins(d, "P_PM", (long)P_PM)) return -1;
11635 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11636 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11637 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11638 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11639 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11640 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11641 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11642 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11643 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11644 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11645 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11646 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11647 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011648#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011649 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11650 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11651 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11652 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11653 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011654#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011655#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011656
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011657#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011658 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011659 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11660 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11661#ifdef SCHED_SPORADIC
11662 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11663#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011664#ifdef SCHED_BATCH
11665 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11666#endif
11667#ifdef SCHED_IDLE
11668 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11669#endif
11670#ifdef SCHED_RESET_ON_FORK
11671 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11672#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011673#ifdef SCHED_SYS
11674 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11675#endif
11676#ifdef SCHED_IA
11677 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11678#endif
11679#ifdef SCHED_FSS
11680 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11681#endif
11682#ifdef SCHED_FX
11683 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11684#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011685#endif
11686
Benjamin Peterson9428d532011-09-14 11:45:52 -040011687#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011688 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11689 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11690 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11691#endif
11692
Victor Stinner8b905bd2011-10-25 13:34:04 +020011693#ifdef RTLD_LAZY
11694 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11695#endif
11696#ifdef RTLD_NOW
11697 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11698#endif
11699#ifdef RTLD_GLOBAL
11700 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11701#endif
11702#ifdef RTLD_LOCAL
11703 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11704#endif
11705#ifdef RTLD_NODELETE
11706 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11707#endif
11708#ifdef RTLD_NOLOAD
11709 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11710#endif
11711#ifdef RTLD_DEEPBIND
11712 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11713#endif
11714
Guido van Rossumd48f2521997-12-05 22:19:34 +000011715#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011716 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011717#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011718 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011719}
11720
11721
Tim Peters5aa91602002-01-30 05:46:57 +000011722#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011723#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011724#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011725
11726#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011727#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011728#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011729
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011730#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011731#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011732#define MODNAME "posix"
11733#endif
11734
Martin v. Löwis1a214512008-06-11 05:26:20 +000011735static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011736 PyModuleDef_HEAD_INIT,
11737 MODNAME,
11738 posix__doc__,
11739 -1,
11740 posix_methods,
11741 NULL,
11742 NULL,
11743 NULL,
11744 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011745};
11746
11747
Larry Hastings9cf065c2012-06-22 16:30:09 -070011748static char *have_functions[] = {
11749
11750#ifdef HAVE_FACCESSAT
11751 "HAVE_FACCESSAT",
11752#endif
11753
11754#ifdef HAVE_FCHDIR
11755 "HAVE_FCHDIR",
11756#endif
11757
11758#ifdef HAVE_FCHMOD
11759 "HAVE_FCHMOD",
11760#endif
11761
11762#ifdef HAVE_FCHMODAT
11763 "HAVE_FCHMODAT",
11764#endif
11765
11766#ifdef HAVE_FCHOWN
11767 "HAVE_FCHOWN",
11768#endif
11769
11770#ifdef HAVE_FEXECVE
11771 "HAVE_FEXECVE",
11772#endif
11773
11774#ifdef HAVE_FDOPENDIR
11775 "HAVE_FDOPENDIR",
11776#endif
11777
Georg Brandl306336b2012-06-24 12:55:33 +020011778#ifdef HAVE_FPATHCONF
11779 "HAVE_FPATHCONF",
11780#endif
11781
Larry Hastings9cf065c2012-06-22 16:30:09 -070011782#ifdef HAVE_FSTATAT
11783 "HAVE_FSTATAT",
11784#endif
11785
11786#ifdef HAVE_FSTATVFS
11787 "HAVE_FSTATVFS",
11788#endif
11789
Georg Brandl306336b2012-06-24 12:55:33 +020011790#ifdef HAVE_FTRUNCATE
11791 "HAVE_FTRUNCATE",
11792#endif
11793
Larry Hastings9cf065c2012-06-22 16:30:09 -070011794#ifdef HAVE_FUTIMENS
11795 "HAVE_FUTIMENS",
11796#endif
11797
11798#ifdef HAVE_FUTIMES
11799 "HAVE_FUTIMES",
11800#endif
11801
11802#ifdef HAVE_FUTIMESAT
11803 "HAVE_FUTIMESAT",
11804#endif
11805
11806#ifdef HAVE_LINKAT
11807 "HAVE_LINKAT",
11808#endif
11809
11810#ifdef HAVE_LCHFLAGS
11811 "HAVE_LCHFLAGS",
11812#endif
11813
11814#ifdef HAVE_LCHMOD
11815 "HAVE_LCHMOD",
11816#endif
11817
11818#ifdef HAVE_LCHOWN
11819 "HAVE_LCHOWN",
11820#endif
11821
11822#ifdef HAVE_LSTAT
11823 "HAVE_LSTAT",
11824#endif
11825
11826#ifdef HAVE_LUTIMES
11827 "HAVE_LUTIMES",
11828#endif
11829
11830#ifdef HAVE_MKDIRAT
11831 "HAVE_MKDIRAT",
11832#endif
11833
11834#ifdef HAVE_MKFIFOAT
11835 "HAVE_MKFIFOAT",
11836#endif
11837
11838#ifdef HAVE_MKNODAT
11839 "HAVE_MKNODAT",
11840#endif
11841
11842#ifdef HAVE_OPENAT
11843 "HAVE_OPENAT",
11844#endif
11845
11846#ifdef HAVE_READLINKAT
11847 "HAVE_READLINKAT",
11848#endif
11849
11850#ifdef HAVE_RENAMEAT
11851 "HAVE_RENAMEAT",
11852#endif
11853
11854#ifdef HAVE_SYMLINKAT
11855 "HAVE_SYMLINKAT",
11856#endif
11857
11858#ifdef HAVE_UNLINKAT
11859 "HAVE_UNLINKAT",
11860#endif
11861
11862#ifdef HAVE_UTIMENSAT
11863 "HAVE_UTIMENSAT",
11864#endif
11865
11866#ifdef MS_WINDOWS
11867 "MS_WINDOWS",
11868#endif
11869
11870 NULL
11871};
11872
11873
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011874PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011875INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011876{
Victor Stinner8c62be82010-05-06 00:08:46 +000011877 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011878 PyObject *list;
11879 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011880
Brian Curtin52173d42010-12-02 18:29:18 +000011881#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011882 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011883#endif
11884
Victor Stinner8c62be82010-05-06 00:08:46 +000011885 m = PyModule_Create(&posixmodule);
11886 if (m == NULL)
11887 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011888
Victor Stinner8c62be82010-05-06 00:08:46 +000011889 /* Initialize environ dictionary */
11890 v = convertenviron();
11891 Py_XINCREF(v);
11892 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11893 return NULL;
11894 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011895
Victor Stinner8c62be82010-05-06 00:08:46 +000011896 if (all_ins(m))
11897 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011898
Victor Stinner8c62be82010-05-06 00:08:46 +000011899 if (setup_confname_tables(m))
11900 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011901
Victor Stinner8c62be82010-05-06 00:08:46 +000011902 Py_INCREF(PyExc_OSError);
11903 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011904
Benjamin Peterson2740af82011-08-02 17:41:34 -050011905#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011906 if (PyType_Ready(&cpu_set_type) < 0)
11907 return NULL;
11908 Py_INCREF(&cpu_set_type);
11909 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011910#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011911
Guido van Rossumb3d39562000-01-31 18:41:26 +000011912#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011913 if (posix_putenv_garbage == NULL)
11914 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011915#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011916
Victor Stinner8c62be82010-05-06 00:08:46 +000011917 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011918#if defined(HAVE_WAITID) && !defined(__APPLE__)
11919 waitid_result_desc.name = MODNAME ".waitid_result";
11920 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11921#endif
11922
Victor Stinner8c62be82010-05-06 00:08:46 +000011923 stat_result_desc.name = MODNAME ".stat_result";
11924 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11925 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11926 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11927 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11928 structseq_new = StatResultType.tp_new;
11929 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011930
Victor Stinner8c62be82010-05-06 00:08:46 +000011931 statvfs_result_desc.name = MODNAME ".statvfs_result";
11932 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011933#ifdef NEED_TICKS_PER_SECOND
11934# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011935 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011936# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011937 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011938# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011939 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011940# endif
11941#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011942
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011943#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011944 sched_param_desc.name = MODNAME ".sched_param";
11945 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11946 SchedParamType.tp_new = sched_param_new;
11947#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011948
11949 /* initialize TerminalSize_info */
11950 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
11951 Py_INCREF(&TerminalSizeType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011952 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011953#if defined(HAVE_WAITID) && !defined(__APPLE__)
11954 Py_INCREF((PyObject*) &WaitidResultType);
11955 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11956#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011957 Py_INCREF((PyObject*) &StatResultType);
11958 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11959 Py_INCREF((PyObject*) &StatVFSResultType);
11960 PyModule_AddObject(m, "statvfs_result",
11961 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011962
11963#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011964 Py_INCREF(&SchedParamType);
11965 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011966#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011967
11968#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011969 /*
11970 * Step 2 of weak-linking support on Mac OS X.
11971 *
11972 * The code below removes functions that are not available on the
11973 * currently active platform.
11974 *
11975 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011976 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011977 * OSX 10.4.
11978 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011979#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011980 if (fstatvfs == NULL) {
11981 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11982 return NULL;
11983 }
11984 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011985#endif /* HAVE_FSTATVFS */
11986
11987#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011988 if (statvfs == NULL) {
11989 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11990 return NULL;
11991 }
11992 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011993#endif /* HAVE_STATVFS */
11994
11995# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011996 if (lchown == NULL) {
11997 if (PyObject_DelAttrString(m, "lchown") == -1) {
11998 return NULL;
11999 }
12000 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012001#endif /* HAVE_LCHOWN */
12002
12003
12004#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012005
12006 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12007
Larry Hastings6fe20b32012-04-19 15:07:49 -070012008 billion = PyLong_FromLong(1000000000);
12009 if (!billion)
12010 return NULL;
12011
Larry Hastings9cf065c2012-06-22 16:30:09 -070012012 /* suppress "function not used" warnings */
12013 {
12014 int ignored;
12015 fd_specified("", -1);
12016 follow_symlinks_specified("", 1);
12017 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12018 dir_fd_converter(Py_None, &ignored);
12019 dir_fd_unavailable(Py_None, &ignored);
12020 }
12021
12022 /*
12023 * provide list of locally available functions
12024 * so os.py can populate support_* lists
12025 */
12026 list = PyList_New(0);
12027 if (!list)
12028 return NULL;
12029 for (trace = have_functions; *trace; trace++) {
12030 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12031 if (!unicode)
12032 return NULL;
12033 if (PyList_Append(list, unicode))
12034 return NULL;
12035 Py_DECREF(unicode);
12036 }
12037 PyModule_AddObject(m, "_have_functions", list);
12038
12039 initialized = 1;
12040
Victor Stinner8c62be82010-05-06 00:08:46 +000012041 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000012042
Guido van Rossumb6775db1994-08-01 11:34:53 +000012043}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012044
12045#ifdef __cplusplus
12046}
12047#endif