blob: 1bd5e97d7b754eba35fbfef874070cd97a590854 [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.
Georg Brandlf7875592012-06-24 13:58:31 +0200525 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700526 * 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 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002424 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002425 * * 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);
Georg Brandlf7875592012-06-24 13:58:31 +02002581
Larry Hastings9cf065c2012-06-22 16:30:09 -07002582exit:
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.
Georg Brandlf7875592012-06-24 13:58:31 +02002999 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003000 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 Hastingsfdaea062012-06-25 04:42:23 -07003275"listdir(path='.') -> list_of_filenames\n\n\
3276Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003277The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003278entries '.' and '..' even if they are present in the directory.\n\
3279\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003280path can be specified as either str or bytes. If path is bytes,\n\
3281 the filenames returned will also be bytes; in all other circumstances\n\
3282 the filenames returned will be str.\n\
3283On some platforms, path may also be specified as an open file descriptor;\n\
3284 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003285 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003286
Barry Warsaw53699e91996-12-10 23:23:01 +00003287static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003288posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003289{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003290 path_t path;
3291 PyObject *list = NULL;
3292 static char *keywords[] = {"path", NULL};
3293 int fd = -1;
3294
3295#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3296 PyObject *v;
3297 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3298 BOOL result;
3299 WIN32_FIND_DATA FileData;
3300 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3301 char *bufptr = namebuf;
3302 /* only claim to have space for MAX_PATH */
3303 Py_ssize_t len = sizeof(namebuf)-5;
3304 PyObject *po = NULL;
3305 wchar_t *wnamebuf = NULL;
3306#elif defined(PYOS_OS2)
3307#ifndef MAX_PATH
3308#define MAX_PATH CCHMAXPATH
3309#endif
3310 char *pt;
3311 PyObject *v;
3312 char namebuf[MAX_PATH+5];
3313 HDIR hdir = 1;
3314 ULONG srchcnt = 1;
3315 FILEFINDBUF3 ep;
3316 APIRET rc;
3317#else
3318 PyObject *v;
3319 DIR *dirp = NULL;
3320 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003321 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003322#endif
3323
3324 memset(&path, 0, sizeof(path));
3325 path.nullable = 1;
3326#ifdef HAVE_FDOPENDIR
3327 path.allow_fd = 1;
3328 path.fd = -1;
3329#endif
3330 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3331 path_converter, &path
3332 ))
3333 return NULL;
3334
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 /* XXX Should redo this putting the (now four) versions of opendir
3336 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003337#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003338 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003339 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003340 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003341
Larry Hastings9cf065c2012-06-22 16:30:09 -07003342 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003343 po_wchars = L".";
3344 len = 1;
3345 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003346 po_wchars = path.wide;
3347 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003348 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003349 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003350 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3351 if (!wnamebuf) {
3352 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003353 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003355 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003357 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003358 if (wch != L'/' && wch != L'\\' && wch != L':')
3359 wnamebuf[len++] = L'\\';
3360 wcscpy(wnamebuf + len, L"*.*");
3361 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003362 if ((list = PyList_New(0)) == NULL) {
3363 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003365 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003366 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003367 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 if (hFindFile == INVALID_HANDLE_VALUE) {
3369 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003370 if (error == ERROR_FILE_NOT_FOUND)
3371 goto exit;
3372 Py_DECREF(list);
3373 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003374 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003376 }
3377 do {
3378 /* Skip over . and .. */
3379 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3380 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003381 v = PyUnicode_FromWideChar(wFileData.cFileName,
3382 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003383 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003384 Py_DECREF(list);
3385 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003386 break;
3387 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003389 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003390 Py_DECREF(list);
3391 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003392 break;
3393 }
3394 Py_DECREF(v);
3395 }
3396 Py_BEGIN_ALLOW_THREADS
3397 result = FindNextFileW(hFindFile, &wFileData);
3398 Py_END_ALLOW_THREADS
3399 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3400 it got to the end of the directory. */
3401 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402 Py_DECREF(list);
3403 list = win32_error_unicode("FindNextFileW", wnamebuf);
3404 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 }
3406 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003407
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003409 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003410 strcpy(namebuf, path.narrow);
3411 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 if (len > 0) {
3413 char ch = namebuf[len-1];
3414 if (ch != SEP && ch != ALTSEP && ch != ':')
3415 namebuf[len++] = '/';
3416 strcpy(namebuf + len, "*.*");
3417 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003418
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003421
Antoine Pitroub73caab2010-08-09 23:39:31 +00003422 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003424 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 if (hFindFile == INVALID_HANDLE_VALUE) {
3426 int error = GetLastError();
3427 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 goto exit;
3429 Py_DECREF(list);
3430 list = win32_error("FindFirstFile", namebuf);
3431 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 }
3433 do {
3434 /* Skip over . and .. */
3435 if (strcmp(FileData.cFileName, ".") != 0 &&
3436 strcmp(FileData.cFileName, "..") != 0) {
3437 v = PyBytes_FromString(FileData.cFileName);
3438 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 Py_DECREF(list);
3440 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003441 break;
3442 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003444 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445 Py_DECREF(list);
3446 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003447 break;
3448 }
3449 Py_DECREF(v);
3450 }
3451 Py_BEGIN_ALLOW_THREADS
3452 result = FindNextFile(hFindFile, &FileData);
3453 Py_END_ALLOW_THREADS
3454 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3455 it got to the end of the directory. */
3456 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 Py_DECREF(list);
3458 list = win32_error("FindNextFile", namebuf);
3459 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 }
3461 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003462
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463exit:
3464 if (hFindFile != INVALID_HANDLE_VALUE) {
3465 if (FindClose(hFindFile) == FALSE) {
3466 if (list != NULL) {
3467 Py_DECREF(list);
3468 list = win32_error_object("FindClose", path.object);
3469 }
3470 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003471 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472 if (wnamebuf)
3473 free(wnamebuf);
3474 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003475
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003477
Tim Peters0bb44a42000-09-15 07:44:49 +00003478#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003480 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003482 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003484 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003485 if (*pt == ALTSEP)
3486 *pt = SEP;
3487 if (namebuf[len-1] != SEP)
3488 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003489 strcpy(namebuf + len, "*.*");
3490
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491 if ((list = PyList_New(0)) == NULL) {
3492 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003493 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003494
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003495 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3496 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003497 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003498 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3499 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3500 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003501
3502 if (rc != NO_ERROR) {
3503 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003504 Py_DECREF(list);
3505 list = posix_error_with_filename(path.narrow);
3506 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003507 }
3508
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003509 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003510 do {
3511 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003512 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003513 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003514
3515 strcpy(namebuf, ep.achName);
3516
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003517 /* Leave Case of Name Alone -- In Native Form */
3518 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003519
Christian Heimes72b710a2008-05-26 13:28:38 +00003520 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003521 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 Py_DECREF(list);
3523 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003524 break;
3525 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003527 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003528 Py_DECREF(list);
3529 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003530 break;
3531 }
3532 Py_DECREF(v);
3533 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3534 }
3535
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536exit:
3537 path_cleanup(&path);
3538
3539 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003540#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003541
Victor Stinner8c62be82010-05-06 00:08:46 +00003542 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543#ifdef HAVE_FDOPENDIR
3544 if (path.fd != -1) {
3545 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003546 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003548 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549
3550 if (fd == -1) {
3551 list = posix_error();
3552 goto exit;
3553 }
3554
Larry Hastingsfdaea062012-06-25 04:42:23 -07003555 return_str = 1;
3556
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 Py_BEGIN_ALLOW_THREADS
3558 dirp = fdopendir(fd);
3559 Py_END_ALLOW_THREADS
3560 }
3561 else
3562#endif
3563 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003564 char *name;
3565 if (path.narrow) {
3566 name = path.narrow;
3567 /* only return bytes if they specified a bytes object */
3568 return_str = !(PyBytes_Check(path.object));
3569 }
3570 else {
3571 name = ".";
3572 return_str = 1;
3573 }
3574
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 Py_BEGIN_ALLOW_THREADS
3576 dirp = opendir(name);
3577 Py_END_ALLOW_THREADS
3578 }
3579
3580 if (dirp == NULL) {
3581 list = path_error("listdir", &path);
3582 goto exit;
3583 }
3584 if ((list = PyList_New(0)) == NULL) {
3585 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003586 }
3587 for (;;) {
3588 errno = 0;
3589 Py_BEGIN_ALLOW_THREADS
3590 ep = readdir(dirp);
3591 Py_END_ALLOW_THREADS
3592 if (ep == NULL) {
3593 if (errno == 0) {
3594 break;
3595 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596 Py_DECREF(list);
3597 list = path_error("listdir", &path);
3598 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 }
3600 }
3601 if (ep->d_name[0] == '.' &&
3602 (NAMLEN(ep) == 1 ||
3603 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3604 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003605 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003606 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3607 else
3608 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003609 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003611 break;
3612 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003614 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003616 break;
3617 }
3618 Py_DECREF(v);
3619 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003620
Larry Hastings9cf065c2012-06-22 16:30:09 -07003621exit:
3622 if (dirp != NULL) {
3623 Py_BEGIN_ALLOW_THREADS
3624 if (fd > -1)
3625 rewinddir(dirp);
3626 closedir(dirp);
3627 Py_END_ALLOW_THREADS
3628 }
3629
3630 path_cleanup(&path);
3631
3632 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003633
Tim Peters0bb44a42000-09-15 07:44:49 +00003634#endif /* which OS */
3635} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003636
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003637#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003638/* A helper function for abspath on win32 */
3639static PyObject *
3640posix__getfullpathname(PyObject *self, PyObject *args)
3641{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003642 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 char outbuf[MAX_PATH*2];
3644 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003645 PyObject *po;
3646
3647 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3648 {
3649 wchar_t *wpath;
3650 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3651 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003652 DWORD result;
3653 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003654
3655 wpath = PyUnicode_AsUnicode(po);
3656 if (wpath == NULL)
3657 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003659 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003661 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003662 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 if (!woutbufp)
3664 return PyErr_NoMemory();
3665 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3666 }
3667 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003668 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003669 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003670 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 if (woutbufp != woutbuf)
3672 free(woutbufp);
3673 return v;
3674 }
3675 /* Drop the argument parsing error as narrow strings
3676 are also valid. */
3677 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003678
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003679 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3680 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003681 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003682 if (win32_warn_bytes_api())
3683 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003684 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003685 outbuf, &temp)) {
3686 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003687 return NULL;
3688 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3690 return PyUnicode_Decode(outbuf, strlen(outbuf),
3691 Py_FileSystemDefaultEncoding, NULL);
3692 }
3693 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003694} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003695
Brian Curtind25aef52011-06-13 15:16:04 -05003696
Brian Curtinf5e76d02010-11-24 13:14:05 +00003697
Brian Curtind40e6f72010-07-08 21:39:08 +00003698/* A helper function for samepath on windows */
3699static PyObject *
3700posix__getfinalpathname(PyObject *self, PyObject *args)
3701{
3702 HANDLE hFile;
3703 int buf_size;
3704 wchar_t *target_path;
3705 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003706 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003707 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003708
Victor Stinnereb5657a2011-09-30 01:44:27 +02003709 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003710 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003711 path = PyUnicode_AsUnicode(po);
3712 if (path == NULL)
3713 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003714
3715 if(!check_GetFinalPathNameByHandle()) {
3716 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3717 NotImplementedError. */
3718 return PyErr_Format(PyExc_NotImplementedError,
3719 "GetFinalPathNameByHandle not available on this platform");
3720 }
3721
3722 hFile = CreateFileW(
3723 path,
3724 0, /* desired access */
3725 0, /* share mode */
3726 NULL, /* security attributes */
3727 OPEN_EXISTING,
3728 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3729 FILE_FLAG_BACKUP_SEMANTICS,
3730 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003731
Victor Stinnereb5657a2011-09-30 01:44:27 +02003732 if(hFile == INVALID_HANDLE_VALUE)
3733 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003734
3735 /* We have a good handle to the target, use it to determine the
3736 target path name. */
3737 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3738
3739 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003740 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003741
3742 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3743 if(!target_path)
3744 return PyErr_NoMemory();
3745
3746 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3747 buf_size, VOLUME_NAME_DOS);
3748 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003749 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003750
3751 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003752 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003753
3754 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003755 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003756 free(target_path);
3757 return result;
3758
3759} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003760
3761static PyObject *
3762posix__getfileinformation(PyObject *self, PyObject *args)
3763{
3764 HANDLE hFile;
3765 BY_HANDLE_FILE_INFORMATION info;
3766 int fd;
3767
3768 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3769 return NULL;
3770
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003771 if (!_PyVerify_fd(fd))
3772 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003773
3774 hFile = (HANDLE)_get_osfhandle(fd);
3775 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003776 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003777
3778 if (!GetFileInformationByHandle(hFile, &info))
3779 return win32_error("_getfileinformation", NULL);
3780
3781 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3782 info.nFileIndexHigh,
3783 info.nFileIndexLow);
3784}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003785
Brian Curtin95d028f2011-06-09 09:10:38 -05003786PyDoc_STRVAR(posix__isdir__doc__,
3787"Return true if the pathname refers to an existing directory.");
3788
Brian Curtin9c669cc2011-06-08 18:17:18 -05003789static PyObject *
3790posix__isdir(PyObject *self, PyObject *args)
3791{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003792 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003793 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003794 DWORD attributes;
3795
3796 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003797 wchar_t *wpath = PyUnicode_AsUnicode(po);
3798 if (wpath == NULL)
3799 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003800
3801 attributes = GetFileAttributesW(wpath);
3802 if (attributes == INVALID_FILE_ATTRIBUTES)
3803 Py_RETURN_FALSE;
3804 goto check;
3805 }
3806 /* Drop the argument parsing error as narrow strings
3807 are also valid. */
3808 PyErr_Clear();
3809
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003810 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003811 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003812 if (win32_warn_bytes_api())
3813 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003814 attributes = GetFileAttributesA(path);
3815 if (attributes == INVALID_FILE_ATTRIBUTES)
3816 Py_RETURN_FALSE;
3817
3818check:
3819 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3820 Py_RETURN_TRUE;
3821 else
3822 Py_RETURN_FALSE;
3823}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003824#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003825
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003826PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003827"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3828Create a directory.\n\
3829\n\
3830If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3831 and path should be relative; path will then be relative to that directory.\n\
3832dir_fd may not be implemented on your platform.\n\
3833 If it is unavailable, using it will raise a NotImplementedError.\n\
3834\n\
3835The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003836
Barry Warsaw53699e91996-12-10 23:23:01 +00003837static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003838posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003839{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003840 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003841 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003842 int dir_fd = DEFAULT_DIR_FD;
3843 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3844 PyObject *return_value = NULL;
3845 int result;
3846
3847 memset(&path, 0, sizeof(path));
3848 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3849 path_converter, &path, &mode,
3850#ifdef HAVE_MKDIRAT
3851 dir_fd_converter, &dir_fd
3852#else
3853 dir_fd_unavailable, &dir_fd
3854#endif
3855 ))
3856 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003857
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003858#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003859 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003860 if (path.wide)
3861 result = CreateDirectoryW(path.wide, NULL);
3862 else
3863 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003864 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003865
Larry Hastings9cf065c2012-06-22 16:30:09 -07003866 if (!result) {
3867 return_value = win32_error_object("mkdir", path.object);
3868 goto exit;
3869 }
3870#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003871 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003872#if HAVE_MKDIRAT
3873 if (dir_fd != DEFAULT_DIR_FD)
3874 result = mkdirat(dir_fd, path.narrow, mode);
3875 else
3876#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003877#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003878 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003879#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003880 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003881#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003882 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003883 if (result < 0) {
3884 return_value = path_error("mkdir", &path);
3885 goto exit;
3886 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003887#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003888 return_value = Py_None;
3889 Py_INCREF(Py_None);
3890exit:
3891 path_cleanup(&path);
3892 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003893}
3894
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003895
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003896/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3897#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003898#include <sys/resource.h>
3899#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003900
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003901
3902#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003903PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003904"nice(inc) -> new_priority\n\n\
3905Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003906
Barry Warsaw53699e91996-12-10 23:23:01 +00003907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003908posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003909{
Victor Stinner8c62be82010-05-06 00:08:46 +00003910 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003911
Victor Stinner8c62be82010-05-06 00:08:46 +00003912 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3913 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003914
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 /* There are two flavours of 'nice': one that returns the new
3916 priority (as required by almost all standards out there) and the
3917 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3918 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003919
Victor Stinner8c62be82010-05-06 00:08:46 +00003920 If we are of the nice family that returns the new priority, we
3921 need to clear errno before the call, and check if errno is filled
3922 before calling posix_error() on a returnvalue of -1, because the
3923 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003924
Victor Stinner8c62be82010-05-06 00:08:46 +00003925 errno = 0;
3926 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003927#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003928 if (value == 0)
3929 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003930#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003931 if (value == -1 && errno != 0)
3932 /* either nice() or getpriority() returned an error */
3933 return posix_error();
3934 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003935}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003936#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003937
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003938
3939#ifdef HAVE_GETPRIORITY
3940PyDoc_STRVAR(posix_getpriority__doc__,
3941"getpriority(which, who) -> current_priority\n\n\
3942Get program scheduling priority.");
3943
3944static PyObject *
3945posix_getpriority(PyObject *self, PyObject *args)
3946{
3947 int which, who, retval;
3948
3949 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3950 return NULL;
3951 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003952 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003953 if (errno != 0)
3954 return posix_error();
3955 return PyLong_FromLong((long)retval);
3956}
3957#endif /* HAVE_GETPRIORITY */
3958
3959
3960#ifdef HAVE_SETPRIORITY
3961PyDoc_STRVAR(posix_setpriority__doc__,
3962"setpriority(which, who, prio) -> None\n\n\
3963Set program scheduling priority.");
3964
3965static PyObject *
3966posix_setpriority(PyObject *self, PyObject *args)
3967{
3968 int which, who, prio, retval;
3969
3970 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3971 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003972 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003973 if (retval == -1)
3974 return posix_error();
3975 Py_RETURN_NONE;
3976}
3977#endif /* HAVE_SETPRIORITY */
3978
3979
Barry Warsaw53699e91996-12-10 23:23:01 +00003980static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003981internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003982{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003983 char *function_name = is_replace ? "replace" : "rename";
3984 path_t src;
3985 path_t dst;
3986 int src_dir_fd = DEFAULT_DIR_FD;
3987 int dst_dir_fd = DEFAULT_DIR_FD;
3988 int dir_fd_specified;
3989 PyObject *return_value = NULL;
3990 char format[24];
3991 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3992
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003993#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003994 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003995 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003996#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003997 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003998#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999
4000 memset(&src, 0, sizeof(src));
4001 memset(&dst, 0, sizeof(dst));
4002 strcpy(format, "O&O&|$O&O&:");
4003 strcat(format, function_name);
4004 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4005 path_converter, &src,
4006 path_converter, &dst,
4007 dir_fd_converter, &src_dir_fd,
4008 dir_fd_converter, &dst_dir_fd))
4009 return NULL;
4010
4011 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4012 (dst_dir_fd != DEFAULT_DIR_FD);
4013#ifndef HAVE_RENAMEAT
4014 if (dir_fd_specified) {
4015 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4016 goto exit;
4017 }
4018#endif
4019
4020 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4021 PyErr_Format(PyExc_ValueError,
4022 "%s: src and dst must be the same type", function_name);
4023 goto exit;
4024 }
4025
4026#ifdef MS_WINDOWS
4027 Py_BEGIN_ALLOW_THREADS
4028 if (src.wide)
4029 result = MoveFileExW(src.wide, dst.wide, flags);
4030 else
4031 result = MoveFileExA(src.narrow, dst.narrow, flags);
4032 Py_END_ALLOW_THREADS
4033
4034 if (!result) {
4035 return_value = win32_error_object(function_name, dst.object);
4036 goto exit;
4037 }
4038
4039#else
4040 Py_BEGIN_ALLOW_THREADS
4041#ifdef HAVE_RENAMEAT
4042 if (dir_fd_specified)
4043 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4044 else
4045#endif
4046 result = rename(src.narrow, dst.narrow);
4047 Py_END_ALLOW_THREADS
4048
4049 if (result) {
4050 return_value = path_error(function_name, &dst);
4051 goto exit;
4052 }
4053#endif
4054
4055 Py_INCREF(Py_None);
4056 return_value = Py_None;
4057exit:
4058 path_cleanup(&src);
4059 path_cleanup(&dst);
4060 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004061}
4062
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004063PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004064"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4065Rename a file or directory.\n\
4066\n\
4067If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4068 descriptor open to a directory, and the respective path string (src or dst)\n\
4069 should be relative; the path will then be relative to that directory.\n\
4070src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4071 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004072
4073static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004074posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004075{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004076 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004077}
4078
4079PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004080"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4081Rename a file or directory, overwriting the destination.\n\
4082\n\
4083If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4084 descriptor open to a directory, and the respective path string (src or dst)\n\
4085 should be relative; the path will then be relative to that directory.\n\
4086src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4087 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004088
4089static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004090posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004091{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004092 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004093}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004094
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004095PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004096"rmdir(path, *, dir_fd=None)\n\n\
4097Remove a directory.\n\
4098\n\
4099If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4100 and path should be relative; path will then be relative to that directory.\n\
4101dir_fd may not be implemented on your platform.\n\
4102 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004103
Barry Warsaw53699e91996-12-10 23:23:01 +00004104static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004105posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004106{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004107 path_t path;
4108 int dir_fd = DEFAULT_DIR_FD;
4109 static char *keywords[] = {"path", "dir_fd", NULL};
4110 int result;
4111 PyObject *return_value = NULL;
4112
4113 memset(&path, 0, sizeof(path));
4114 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4115 path_converter, &path,
4116#ifdef HAVE_UNLINKAT
4117 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004118#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004119 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004120#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004121 ))
4122 return NULL;
4123
4124 Py_BEGIN_ALLOW_THREADS
4125#ifdef MS_WINDOWS
4126 if (path.wide)
4127 result = RemoveDirectoryW(path.wide);
4128 else
4129 result = RemoveDirectoryA(path.narrow);
4130 result = !result; /* Windows, success=1, UNIX, success=0 */
4131#else
4132#ifdef HAVE_UNLINKAT
4133 if (dir_fd != DEFAULT_DIR_FD)
4134 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4135 else
4136#endif
4137 result = rmdir(path.narrow);
4138#endif
4139 Py_END_ALLOW_THREADS
4140
4141 if (result) {
4142 return_value = path_error("rmdir", &path);
4143 goto exit;
4144 }
4145
4146 return_value = Py_None;
4147 Py_INCREF(Py_None);
4148
4149exit:
4150 path_cleanup(&path);
4151 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004152}
4153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004154
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004155#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004156PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004157"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004158Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004159
Barry Warsaw53699e91996-12-10 23:23:01 +00004160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004161posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004162{
Victor Stinner8c62be82010-05-06 00:08:46 +00004163 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004164#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004165 wchar_t *command;
4166 if (!PyArg_ParseTuple(args, "u:system", &command))
4167 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004168
Victor Stinner8c62be82010-05-06 00:08:46 +00004169 Py_BEGIN_ALLOW_THREADS
4170 sts = _wsystem(command);
4171 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004172#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004173 PyObject *command_obj;
4174 char *command;
4175 if (!PyArg_ParseTuple(args, "O&:system",
4176 PyUnicode_FSConverter, &command_obj))
4177 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004178
Victor Stinner8c62be82010-05-06 00:08:46 +00004179 command = PyBytes_AsString(command_obj);
4180 Py_BEGIN_ALLOW_THREADS
4181 sts = system(command);
4182 Py_END_ALLOW_THREADS
4183 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004184#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004185 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004186}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004187#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004189
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004190PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004191"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004192Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004193
Barry Warsaw53699e91996-12-10 23:23:01 +00004194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004195posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004196{
Victor Stinner8c62be82010-05-06 00:08:46 +00004197 int i;
4198 if (!PyArg_ParseTuple(args, "i:umask", &i))
4199 return NULL;
4200 i = (int)umask(i);
4201 if (i < 0)
4202 return posix_error();
4203 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004204}
4205
Brian Curtind40e6f72010-07-08 21:39:08 +00004206#ifdef MS_WINDOWS
4207
4208/* override the default DeleteFileW behavior so that directory
4209symlinks can be removed with this function, the same as with
4210Unix symlinks */
4211BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4212{
4213 WIN32_FILE_ATTRIBUTE_DATA info;
4214 WIN32_FIND_DATAW find_data;
4215 HANDLE find_data_handle;
4216 int is_directory = 0;
4217 int is_link = 0;
4218
4219 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4220 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004221
Brian Curtind40e6f72010-07-08 21:39:08 +00004222 /* Get WIN32_FIND_DATA structure for the path to determine if
4223 it is a symlink */
4224 if(is_directory &&
4225 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4226 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4227
4228 if(find_data_handle != INVALID_HANDLE_VALUE) {
4229 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4230 FindClose(find_data_handle);
4231 }
4232 }
4233 }
4234
4235 if (is_directory && is_link)
4236 return RemoveDirectoryW(lpFileName);
4237
4238 return DeleteFileW(lpFileName);
4239}
4240#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004241
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004242PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004243"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004244Remove a file (same as remove()).\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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004251PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004252"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004253Remove a file (same as unlink()).\n\
4254\n\
4255If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4256 and path should be relative; path will then be relative to that directory.\n\
4257dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004258 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004259
Barry Warsaw53699e91996-12-10 23:23:01 +00004260static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004261posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004262{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004263 path_t path;
4264 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004265 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004266 int result;
4267 PyObject *return_value = NULL;
4268
4269 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004270 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004271 path_converter, &path,
4272#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004273 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004274#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004275 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004276#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004277 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004278 return NULL;
4279
4280 Py_BEGIN_ALLOW_THREADS
4281#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004282 if (path.wide)
4283 result = Py_DeleteFileW(path.wide);
4284 else
4285 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004286 result = !result; /* Windows, success=1, UNIX, success=0 */
4287#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004288#ifdef HAVE_UNLINKAT
4289 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004290 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004291 else
4292#endif /* HAVE_UNLINKAT */
4293 result = unlink(path.narrow);
4294#endif
4295 Py_END_ALLOW_THREADS
4296
4297 if (result) {
4298 return_value = path_error("unlink", &path);
4299 goto exit;
4300 }
4301
4302 return_value = Py_None;
4303 Py_INCREF(Py_None);
4304
4305exit:
4306 path_cleanup(&path);
4307 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004308}
4309
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004310
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004311PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004312"uname() -> uname_result\n\n\
4313Return an object identifying the current operating system.\n\
4314The object behaves like a named tuple with the following fields:\n\
4315 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004316
Larry Hastings605a62d2012-06-24 04:33:36 -07004317static PyStructSequence_Field uname_result_fields[] = {
4318 {"sysname", "operating system name"},
4319 {"nodename", "name of machine on network (implementation-defined)"},
4320 {"release", "operating system release"},
4321 {"version", "operating system version"},
4322 {"machine", "hardware identifier"},
4323 {NULL}
4324};
4325
4326PyDoc_STRVAR(uname_result__doc__,
4327"uname_result: Result from os.uname().\n\n\
4328This object may be accessed either as a tuple of\n\
4329 (sysname, nodename, release, version, machine),\n\
4330or via the attributes sysname, nodename, release, version, and machine.\n\
4331\n\
4332See os.uname for more information.");
4333
4334static PyStructSequence_Desc uname_result_desc = {
4335 "uname_result", /* name */
4336 uname_result__doc__, /* doc */
4337 uname_result_fields,
4338 5
4339};
4340
4341static PyTypeObject UnameResultType;
4342
4343
4344#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004345static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004346posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004347{
Victor Stinner8c62be82010-05-06 00:08:46 +00004348 struct utsname u;
4349 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004350 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004351
Victor Stinner8c62be82010-05-06 00:08:46 +00004352 Py_BEGIN_ALLOW_THREADS
4353 res = uname(&u);
4354 Py_END_ALLOW_THREADS
4355 if (res < 0)
4356 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004357
4358 value = PyStructSequence_New(&UnameResultType);
4359 if (value == NULL)
4360 return NULL;
4361
4362#define SET(i, field) \
4363 { \
4364 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4365 if (!o) { \
4366 Py_DECREF(value); \
4367 return NULL; \
4368 } \
4369 PyStructSequence_SET_ITEM(value, i, o); \
4370 } \
4371
4372 SET(0, u.sysname);
4373 SET(1, u.nodename);
4374 SET(2, u.release);
4375 SET(3, u.version);
4376 SET(4, u.machine);
4377
4378#undef SET
4379
4380 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004381}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004382#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004383
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004384
Larry Hastings9cf065c2012-06-22 16:30:09 -07004385PyDoc_STRVAR(posix_utime__doc__,
4386"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4387Set the access and modified time of path.\n\
4388\n\
4389path may always be specified as a string.\n\
4390On some platforms, path may also be specified as an open file descriptor.\n\
4391 If this functionality is unavailable, using it raises an exception.\n\
4392\n\
4393If times is not None, it must be a tuple (atime, mtime);\n\
4394 atime and mtime should be expressed as float seconds since the epoch.\n\
4395If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4396 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4397 since the epoch.\n\
4398If both times and ns are None, utime uses the current time.\n\
4399Specifying tuples for both times and ns is an error.\n\
4400\n\
4401If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4402 and path should be relative; path will then be relative to that directory.\n\
4403If follow_symlinks is False, and the last element of the path is a symbolic\n\
4404 link, utime will modify the symbolic link itself instead of the file the\n\
4405 link points to.\n\
4406It is an error to use dir_fd or follow_symlinks when specifying path\n\
4407 as an open file descriptor.\n\
4408dir_fd and follow_symlinks may not be available on your platform.\n\
4409 If they are unavailable, using them will raise a NotImplementedError.");
4410
4411typedef struct {
4412 int now;
4413 time_t atime_s;
4414 long atime_ns;
4415 time_t mtime_s;
4416 long mtime_ns;
4417} utime_t;
4418
4419/*
4420 * these macros assume that "utime" is a pointer to a utime_t
4421 * they also intentionally leak the declaration of a pointer named "time"
4422 */
4423#define UTIME_TO_TIMESPEC \
4424 struct timespec ts[2]; \
4425 struct timespec *time; \
4426 if (utime->now) \
4427 time = NULL; \
4428 else { \
4429 ts[0].tv_sec = utime->atime_s; \
4430 ts[0].tv_nsec = utime->atime_ns; \
4431 ts[1].tv_sec = utime->mtime_s; \
4432 ts[1].tv_nsec = utime->mtime_ns; \
4433 time = ts; \
4434 } \
4435
4436#define UTIME_TO_TIMEVAL \
4437 struct timeval tv[2]; \
4438 struct timeval *time; \
4439 if (utime->now) \
4440 time = NULL; \
4441 else { \
4442 tv[0].tv_sec = utime->atime_s; \
4443 tv[0].tv_usec = utime->atime_ns / 1000; \
4444 tv[1].tv_sec = utime->mtime_s; \
4445 tv[1].tv_usec = utime->mtime_ns / 1000; \
4446 time = tv; \
4447 } \
4448
4449#define UTIME_TO_UTIMBUF \
4450 struct utimbuf u[2]; \
4451 struct utimbuf *time; \
4452 if (utime->now) \
4453 time = NULL; \
4454 else { \
4455 u.actime = utime->atime_s; \
4456 u.modtime = utime->mtime_s; \
4457 time = u; \
4458 }
4459
4460#define UTIME_TO_TIME_T \
4461 time_t timet[2]; \
4462 struct timet time; \
4463 if (utime->now) \
4464 time = NULL; \
4465 else { \
4466 timet[0] = utime->atime_s; \
4467 timet[1] = utime->mtime_s; \
4468 time = &timet; \
4469 } \
4470
4471
4472#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4473
4474#if UTIME_HAVE_DIR_FD
4475
4476static int
4477utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4478{
4479#ifdef HAVE_UTIMENSAT
4480 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4481 UTIME_TO_TIMESPEC;
4482 return utimensat(dir_fd, path, time, flags);
4483#elif defined(HAVE_FUTIMESAT)
4484 UTIME_TO_TIMEVAL;
4485 /*
4486 * follow_symlinks will never be false here;
4487 * we only allow !follow_symlinks and dir_fd together
4488 * if we have utimensat()
4489 */
4490 assert(follow_symlinks);
4491 return futimesat(dir_fd, path, time);
4492#endif
4493}
4494
4495#endif
4496
4497#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4498
4499#if UTIME_HAVE_FD
4500
4501static int
4502utime_fd(utime_t *utime, int fd)
4503{
4504#ifdef HAVE_FUTIMENS
4505 UTIME_TO_TIMESPEC;
4506 return futimens(fd, time);
4507#else
4508 UTIME_TO_TIMEVAL;
4509 return futimes(fd, time);
4510#endif
4511}
4512
4513#endif
4514
4515
4516#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4517 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4518
4519#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4520
4521static int
4522utime_nofollow_symlinks(utime_t *utime, char *path)
4523{
4524#ifdef HAVE_UTIMENSAT
4525 UTIME_TO_TIMESPEC;
4526 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4527#else
4528 UTIME_TO_TIMEVAL;
4529 return lutimes(path, time);
4530#endif
4531}
4532
4533#endif
4534
4535#ifndef MS_WINDOWS
4536
4537static int
4538utime_default(utime_t *utime, char *path)
4539{
4540#ifdef HAVE_UTIMENSAT
4541 UTIME_TO_TIMESPEC;
4542 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4543#elif defined(HAVE_UTIMES)
4544 UTIME_TO_TIMEVAL;
4545 return utimes(path, time);
4546#elif defined(HAVE_UTIME_H)
4547 UTIME_TO_UTIMBUF;
4548 return utime(path, time);
4549#else
4550 UTIME_TO_TIME_T;
4551 return utime(path, time);
4552#endif
4553}
4554
4555#endif
4556
Larry Hastings76ad59b2012-05-03 00:30:07 -07004557static int
4558split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4559{
4560 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004561 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004562 divmod = PyNumber_Divmod(py_long, billion);
4563 if (!divmod)
4564 goto exit;
4565 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4566 if ((*s == -1) && PyErr_Occurred())
4567 goto exit;
4568 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004569 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004570 goto exit;
4571
4572 result = 1;
4573exit:
4574 Py_XDECREF(divmod);
4575 return result;
4576}
4577
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578static PyObject *
4579posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004580{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004582 PyObject *times = NULL;
4583 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584 int dir_fd = DEFAULT_DIR_FD;
4585 int follow_symlinks = 1;
4586 char *keywords[] = {"path", "times", "ns", "dir_fd",
4587 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004588
Larry Hastings9cf065c2012-06-22 16:30:09 -07004589 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004590
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591#ifdef MS_WINDOWS
4592 HANDLE hFile;
4593 FILETIME atime, mtime;
4594#else
4595 int result;
4596#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004597
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004599
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600 memset(&path, 0, sizeof(path));
4601#if UTIME_HAVE_FD
4602 path.allow_fd = 1;
4603#endif
4604 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4605 "O&|O$OO&p:utime", keywords,
4606 path_converter, &path,
4607 &times, &ns,
4608#if UTIME_HAVE_DIR_FD
4609 dir_fd_converter, &dir_fd,
4610#else
4611 dir_fd_unavailable, &dir_fd,
4612#endif
4613 &follow_symlinks
4614 ))
4615 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004616
Larry Hastings9cf065c2012-06-22 16:30:09 -07004617 if (times && (times != Py_None) && ns) {
4618 PyErr_SetString(PyExc_ValueError,
4619 "utime: you may specify either 'times'"
4620 " or 'ns' but not both");
4621 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004622 }
4623
4624 if (times && (times != Py_None)) {
4625 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004626 PyErr_SetString(PyExc_TypeError,
4627 "utime: 'times' must be either"
4628 " a tuple of two ints or None");
4629 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004630 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004632 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004633 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004634 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004635 &utime.mtime_s, &utime.mtime_ns) == -1) {
4636 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004637 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004638 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004640 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004641 PyErr_SetString(PyExc_TypeError,
4642 "utime: 'ns' must be a tuple of two ints");
4643 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004644 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004645 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004646 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004648 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649 &utime.mtime_s, &utime.mtime_ns)) {
4650 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004651 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652 }
4653 else {
4654 /* times and ns are both None/unspecified. use "now". */
4655 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004656 }
4657
Larry Hastings9cf065c2012-06-22 16:30:09 -07004658#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4659 if (follow_symlinks_specified("utime", follow_symlinks))
4660 goto exit;
4661#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004662
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4664 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4665 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4666 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004667
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668#if !defined(HAVE_UTIMENSAT)
4669 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004670 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 "utime: cannot use dir_fd and follow_symlinks "
4672 "together on this platform");
4673 goto exit;
4674 }
4675#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004676
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004677#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004678 Py_BEGIN_ALLOW_THREADS
4679 if (path.wide)
4680 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004681 NULL, OPEN_EXISTING,
4682 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683 else
4684 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004685 NULL, OPEN_EXISTING,
4686 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004687 Py_END_ALLOW_THREADS
4688 if (hFile == INVALID_HANDLE_VALUE) {
4689 win32_error_object("utime", path.object);
4690 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004691 }
4692
Larry Hastings9cf065c2012-06-22 16:30:09 -07004693 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004694 SYSTEMTIME now;
4695 GetSystemTime(&now);
4696 if (!SystemTimeToFileTime(&now, &mtime) ||
4697 !SystemTimeToFileTime(&now, &atime)) {
4698 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004699 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004700 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004701 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004702 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4704 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004705 }
4706 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4707 /* Avoid putting the file name into the error here,
4708 as that may confuse the user into believing that
4709 something is wrong with the file, when it also
4710 could be the time stamp that gives a problem. */
4711 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004713 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004714#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004716
Larry Hastings9cf065c2012-06-22 16:30:09 -07004717#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4718 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4719 result = utime_nofollow_symlinks(&utime, path.narrow);
4720 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004721#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722
4723#if UTIME_HAVE_DIR_FD
4724 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4725 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4726 else
4727#endif
4728
4729#if UTIME_HAVE_FD
4730 if (path.fd != -1)
4731 result = utime_fd(&utime, path.fd);
4732 else
4733#endif
4734
4735 result = utime_default(&utime, path.narrow);
4736
4737 Py_END_ALLOW_THREADS
4738
4739 if (result < 0) {
4740 /* see previous comment about not putting filename in error here */
4741 return_value = posix_error();
4742 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004743 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004744
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004745#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746
4747 Py_INCREF(Py_None);
4748 return_value = Py_None;
4749
4750exit:
4751 path_cleanup(&path);
4752#ifdef MS_WINDOWS
4753 if (hFile != INVALID_HANDLE_VALUE)
4754 CloseHandle(hFile);
4755#endif
4756 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004757}
4758
Guido van Rossum3b066191991-06-04 19:40:25 +00004759/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004760
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004761PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004762"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004763Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004764
Barry Warsaw53699e91996-12-10 23:23:01 +00004765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004766posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004767{
Victor Stinner8c62be82010-05-06 00:08:46 +00004768 int sts;
4769 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4770 return NULL;
4771 _exit(sts);
4772 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004773}
4774
Martin v. Löwis114619e2002-10-07 06:44:21 +00004775#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4776static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004777free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004778{
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 Py_ssize_t i;
4780 for (i = 0; i < count; i++)
4781 PyMem_Free(array[i]);
4782 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004783}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004784
Antoine Pitrou69f71142009-05-24 21:25:49 +00004785static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004786int fsconvert_strdup(PyObject *o, char**out)
4787{
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 PyObject *bytes;
4789 Py_ssize_t size;
4790 if (!PyUnicode_FSConverter(o, &bytes))
4791 return 0;
4792 size = PyBytes_GET_SIZE(bytes);
4793 *out = PyMem_Malloc(size+1);
4794 if (!*out)
4795 return 0;
4796 memcpy(*out, PyBytes_AsString(bytes), size+1);
4797 Py_DECREF(bytes);
4798 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004799}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004800#endif
4801
Ross Lagerwall7807c352011-03-17 20:20:30 +02004802#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004803static char**
4804parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4805{
Victor Stinner8c62be82010-05-06 00:08:46 +00004806 char **envlist;
4807 Py_ssize_t i, pos, envc;
4808 PyObject *keys=NULL, *vals=NULL;
4809 PyObject *key, *val, *key2, *val2;
4810 char *p, *k, *v;
4811 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004812
Victor Stinner8c62be82010-05-06 00:08:46 +00004813 i = PyMapping_Size(env);
4814 if (i < 0)
4815 return NULL;
4816 envlist = PyMem_NEW(char *, i + 1);
4817 if (envlist == NULL) {
4818 PyErr_NoMemory();
4819 return NULL;
4820 }
4821 envc = 0;
4822 keys = PyMapping_Keys(env);
4823 vals = PyMapping_Values(env);
4824 if (!keys || !vals)
4825 goto error;
4826 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4827 PyErr_Format(PyExc_TypeError,
4828 "env.keys() or env.values() is not a list");
4829 goto error;
4830 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004831
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 for (pos = 0; pos < i; pos++) {
4833 key = PyList_GetItem(keys, pos);
4834 val = PyList_GetItem(vals, pos);
4835 if (!key || !val)
4836 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004837
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 if (PyUnicode_FSConverter(key, &key2) == 0)
4839 goto error;
4840 if (PyUnicode_FSConverter(val, &val2) == 0) {
4841 Py_DECREF(key2);
4842 goto error;
4843 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004844
4845#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004846 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4847 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004848#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004849 k = PyBytes_AsString(key2);
4850 v = PyBytes_AsString(val2);
4851 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004852
Victor Stinner8c62be82010-05-06 00:08:46 +00004853 p = PyMem_NEW(char, len);
4854 if (p == NULL) {
4855 PyErr_NoMemory();
4856 Py_DECREF(key2);
4857 Py_DECREF(val2);
4858 goto error;
4859 }
4860 PyOS_snprintf(p, len, "%s=%s", k, v);
4861 envlist[envc++] = p;
4862 Py_DECREF(key2);
4863 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004864#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004865 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004866#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 }
4868 Py_DECREF(vals);
4869 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004870
Victor Stinner8c62be82010-05-06 00:08:46 +00004871 envlist[envc] = 0;
4872 *envc_ptr = envc;
4873 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004874
4875error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004876 Py_XDECREF(keys);
4877 Py_XDECREF(vals);
4878 while (--envc >= 0)
4879 PyMem_DEL(envlist[envc]);
4880 PyMem_DEL(envlist);
4881 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004882}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004883
Ross Lagerwall7807c352011-03-17 20:20:30 +02004884static char**
4885parse_arglist(PyObject* argv, Py_ssize_t *argc)
4886{
4887 int i;
4888 char **argvlist = PyMem_NEW(char *, *argc+1);
4889 if (argvlist == NULL) {
4890 PyErr_NoMemory();
4891 return NULL;
4892 }
4893 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004894 PyObject* item = PySequence_ITEM(argv, i);
4895 if (item == NULL)
4896 goto fail;
4897 if (!fsconvert_strdup(item, &argvlist[i])) {
4898 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004899 goto fail;
4900 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004901 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004902 }
4903 argvlist[*argc] = NULL;
4904 return argvlist;
4905fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004906 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004907 free_string_array(argvlist, *argc);
4908 return NULL;
4909}
4910#endif
4911
4912#ifdef HAVE_EXECV
4913PyDoc_STRVAR(posix_execv__doc__,
4914"execv(path, args)\n\n\
4915Execute an executable path with arguments, replacing current process.\n\
4916\n\
4917 path: path of executable file\n\
4918 args: tuple or list of strings");
4919
4920static PyObject *
4921posix_execv(PyObject *self, PyObject *args)
4922{
4923 PyObject *opath;
4924 char *path;
4925 PyObject *argv;
4926 char **argvlist;
4927 Py_ssize_t argc;
4928
4929 /* execv has two arguments: (path, argv), where
4930 argv is a list or tuple of strings. */
4931
4932 if (!PyArg_ParseTuple(args, "O&O:execv",
4933 PyUnicode_FSConverter,
4934 &opath, &argv))
4935 return NULL;
4936 path = PyBytes_AsString(opath);
4937 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4938 PyErr_SetString(PyExc_TypeError,
4939 "execv() arg 2 must be a tuple or list");
4940 Py_DECREF(opath);
4941 return NULL;
4942 }
4943 argc = PySequence_Size(argv);
4944 if (argc < 1) {
4945 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4946 Py_DECREF(opath);
4947 return NULL;
4948 }
4949
4950 argvlist = parse_arglist(argv, &argc);
4951 if (argvlist == NULL) {
4952 Py_DECREF(opath);
4953 return NULL;
4954 }
4955
4956 execv(path, argvlist);
4957
4958 /* If we get here it's definitely an error */
4959
4960 free_string_array(argvlist, argc);
4961 Py_DECREF(opath);
4962 return posix_error();
4963}
4964
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004965PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004966"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004967Execute a path with arguments and environment, replacing current process.\n\
4968\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 path: path of executable file\n\
4970 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004971 env: dictionary of strings mapping to strings\n\
4972\n\
4973On some platforms, you may specify an open file descriptor for path;\n\
4974 execve will execute the program the file descriptor is open to.\n\
4975 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004976
Barry Warsaw53699e91996-12-10 23:23:01 +00004977static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004978posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004979{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004980 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004982 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004983 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004984 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004986
Victor Stinner8c62be82010-05-06 00:08:46 +00004987 /* execve has three arguments: (path, argv, env), where
4988 argv is a list or tuple of strings and env is a dictionary
4989 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004990
Larry Hastings9cf065c2012-06-22 16:30:09 -07004991 memset(&path, 0, sizeof(path));
4992#ifdef HAVE_FEXECVE
4993 path.allow_fd = 1;
4994#endif
4995 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4996 path_converter, &path,
4997 &argv, &env
4998 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005000
Ross Lagerwall7807c352011-03-17 20:20:30 +02005001 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005002 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005003 "execve: argv must be a tuple or list");
5004 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005005 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005006 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005007 if (!PyMapping_Check(env)) {
5008 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005009 "execve: environment must be a mapping object");
5010 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005011 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005012
Ross Lagerwall7807c352011-03-17 20:20:30 +02005013 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005014 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005015 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005016 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005017
Victor Stinner8c62be82010-05-06 00:08:46 +00005018 envlist = parse_envlist(env, &envc);
5019 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005020 goto fail;
5021
Larry Hastings9cf065c2012-06-22 16:30:09 -07005022#ifdef HAVE_FEXECVE
5023 if (path.fd > -1)
5024 fexecve(path.fd, argvlist, envlist);
5025 else
5026#endif
5027 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005028
5029 /* If we get here it's definitely an error */
5030
Larry Hastings9cf065c2012-06-22 16:30:09 -07005031 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005032
5033 while (--envc >= 0)
5034 PyMem_DEL(envlist[envc]);
5035 PyMem_DEL(envlist);
5036 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005037 if (argvlist)
5038 free_string_array(argvlist, argc);
5039 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005040 return NULL;
5041}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005042#endif /* HAVE_EXECV */
5043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005044
Guido van Rossuma1065681999-01-25 23:20:23 +00005045#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005046PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005047"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005048Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005049\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005050 mode: mode of process creation\n\
5051 path: path of executable file\n\
5052 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005053
5054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005055posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005056{
Victor Stinner8c62be82010-05-06 00:08:46 +00005057 PyObject *opath;
5058 char *path;
5059 PyObject *argv;
5060 char **argvlist;
5061 int mode, i;
5062 Py_ssize_t argc;
5063 Py_intptr_t spawnval;
5064 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005065
Victor Stinner8c62be82010-05-06 00:08:46 +00005066 /* spawnv has three arguments: (mode, path, argv), where
5067 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005068
Victor Stinner8c62be82010-05-06 00:08:46 +00005069 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5070 PyUnicode_FSConverter,
5071 &opath, &argv))
5072 return NULL;
5073 path = PyBytes_AsString(opath);
5074 if (PyList_Check(argv)) {
5075 argc = PyList_Size(argv);
5076 getitem = PyList_GetItem;
5077 }
5078 else if (PyTuple_Check(argv)) {
5079 argc = PyTuple_Size(argv);
5080 getitem = PyTuple_GetItem;
5081 }
5082 else {
5083 PyErr_SetString(PyExc_TypeError,
5084 "spawnv() arg 2 must be a tuple or list");
5085 Py_DECREF(opath);
5086 return NULL;
5087 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005088
Victor Stinner8c62be82010-05-06 00:08:46 +00005089 argvlist = PyMem_NEW(char *, argc+1);
5090 if (argvlist == NULL) {
5091 Py_DECREF(opath);
5092 return PyErr_NoMemory();
5093 }
5094 for (i = 0; i < argc; i++) {
5095 if (!fsconvert_strdup((*getitem)(argv, i),
5096 &argvlist[i])) {
5097 free_string_array(argvlist, i);
5098 PyErr_SetString(
5099 PyExc_TypeError,
5100 "spawnv() arg 2 must contain only strings");
5101 Py_DECREF(opath);
5102 return NULL;
5103 }
5104 }
5105 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005106
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005107#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 Py_BEGIN_ALLOW_THREADS
5109 spawnval = spawnv(mode, path, argvlist);
5110 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005111#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005112 if (mode == _OLD_P_OVERLAY)
5113 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005114
Victor Stinner8c62be82010-05-06 00:08:46 +00005115 Py_BEGIN_ALLOW_THREADS
5116 spawnval = _spawnv(mode, path, argvlist);
5117 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005118#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005119
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 free_string_array(argvlist, argc);
5121 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005122
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 if (spawnval == -1)
5124 return posix_error();
5125 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005126#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005127 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005128#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005129 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005130#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005131}
5132
5133
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005134PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005135"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005136Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005137\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 mode: mode of process creation\n\
5139 path: path of executable file\n\
5140 args: tuple or list of arguments\n\
5141 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005142
5143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005144posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005145{
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 PyObject *opath;
5147 char *path;
5148 PyObject *argv, *env;
5149 char **argvlist;
5150 char **envlist;
5151 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005152 int mode;
5153 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005154 Py_intptr_t spawnval;
5155 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5156 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005157
Victor Stinner8c62be82010-05-06 00:08:46 +00005158 /* spawnve has four arguments: (mode, path, argv, env), where
5159 argv is a list or tuple of strings and env is a dictionary
5160 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005161
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5163 PyUnicode_FSConverter,
5164 &opath, &argv, &env))
5165 return NULL;
5166 path = PyBytes_AsString(opath);
5167 if (PyList_Check(argv)) {
5168 argc = PyList_Size(argv);
5169 getitem = PyList_GetItem;
5170 }
5171 else if (PyTuple_Check(argv)) {
5172 argc = PyTuple_Size(argv);
5173 getitem = PyTuple_GetItem;
5174 }
5175 else {
5176 PyErr_SetString(PyExc_TypeError,
5177 "spawnve() arg 2 must be a tuple or list");
5178 goto fail_0;
5179 }
5180 if (!PyMapping_Check(env)) {
5181 PyErr_SetString(PyExc_TypeError,
5182 "spawnve() arg 3 must be a mapping object");
5183 goto fail_0;
5184 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005185
Victor Stinner8c62be82010-05-06 00:08:46 +00005186 argvlist = PyMem_NEW(char *, argc+1);
5187 if (argvlist == NULL) {
5188 PyErr_NoMemory();
5189 goto fail_0;
5190 }
5191 for (i = 0; i < argc; i++) {
5192 if (!fsconvert_strdup((*getitem)(argv, i),
5193 &argvlist[i]))
5194 {
5195 lastarg = i;
5196 goto fail_1;
5197 }
5198 }
5199 lastarg = argc;
5200 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005201
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 envlist = parse_envlist(env, &envc);
5203 if (envlist == NULL)
5204 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005205
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005206#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 Py_BEGIN_ALLOW_THREADS
5208 spawnval = spawnve(mode, path, argvlist, envlist);
5209 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005210#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005211 if (mode == _OLD_P_OVERLAY)
5212 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005213
Victor Stinner8c62be82010-05-06 00:08:46 +00005214 Py_BEGIN_ALLOW_THREADS
5215 spawnval = _spawnve(mode, path, argvlist, envlist);
5216 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005217#endif
Tim Peters25059d32001-12-07 20:35:43 +00005218
Victor Stinner8c62be82010-05-06 00:08:46 +00005219 if (spawnval == -1)
5220 (void) posix_error();
5221 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005222#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005223 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005224#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005226#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005227
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 while (--envc >= 0)
5229 PyMem_DEL(envlist[envc]);
5230 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005231 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005232 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005233 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005234 Py_DECREF(opath);
5235 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005236}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005237
5238/* OS/2 supports spawnvp & spawnvpe natively */
5239#if defined(PYOS_OS2)
5240PyDoc_STRVAR(posix_spawnvp__doc__,
5241"spawnvp(mode, file, args)\n\n\
5242Execute the program 'file' in a new process, using the environment\n\
5243search path to find the file.\n\
5244\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005245 mode: mode of process creation\n\
5246 file: executable file name\n\
5247 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005248
5249static PyObject *
5250posix_spawnvp(PyObject *self, PyObject *args)
5251{
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 PyObject *opath;
5253 char *path;
5254 PyObject *argv;
5255 char **argvlist;
5256 int mode, i, argc;
5257 Py_intptr_t spawnval;
5258 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005259
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 /* spawnvp has three arguments: (mode, path, argv), where
5261 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005262
Victor Stinner8c62be82010-05-06 00:08:46 +00005263 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5264 PyUnicode_FSConverter,
5265 &opath, &argv))
5266 return NULL;
5267 path = PyBytes_AsString(opath);
5268 if (PyList_Check(argv)) {
5269 argc = PyList_Size(argv);
5270 getitem = PyList_GetItem;
5271 }
5272 else if (PyTuple_Check(argv)) {
5273 argc = PyTuple_Size(argv);
5274 getitem = PyTuple_GetItem;
5275 }
5276 else {
5277 PyErr_SetString(PyExc_TypeError,
5278 "spawnvp() arg 2 must be a tuple or list");
5279 Py_DECREF(opath);
5280 return NULL;
5281 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005282
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 argvlist = PyMem_NEW(char *, argc+1);
5284 if (argvlist == NULL) {
5285 Py_DECREF(opath);
5286 return PyErr_NoMemory();
5287 }
5288 for (i = 0; i < argc; i++) {
5289 if (!fsconvert_strdup((*getitem)(argv, i),
5290 &argvlist[i])) {
5291 free_string_array(argvlist, i);
5292 PyErr_SetString(
5293 PyExc_TypeError,
5294 "spawnvp() arg 2 must contain only strings");
5295 Py_DECREF(opath);
5296 return NULL;
5297 }
5298 }
5299 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005300
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005302#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005303 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005304#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005305 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005306#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005307 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005308
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 free_string_array(argvlist, argc);
5310 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005311
Victor Stinner8c62be82010-05-06 00:08:46 +00005312 if (spawnval == -1)
5313 return posix_error();
5314 else
5315 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005316}
5317
5318
5319PyDoc_STRVAR(posix_spawnvpe__doc__,
5320"spawnvpe(mode, file, args, env)\n\n\
5321Execute the program 'file' in a new process, using the environment\n\
5322search path to find the file.\n\
5323\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005324 mode: mode of process creation\n\
5325 file: executable file name\n\
5326 args: tuple or list of arguments\n\
5327 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005328
5329static PyObject *
5330posix_spawnvpe(PyObject *self, PyObject *args)
5331{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005332 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005333 char *path;
5334 PyObject *argv, *env;
5335 char **argvlist;
5336 char **envlist;
5337 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005338 int mode;
5339 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005340 Py_intptr_t spawnval;
5341 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5342 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005343
Victor Stinner8c62be82010-05-06 00:08:46 +00005344 /* spawnvpe has four arguments: (mode, path, argv, env), where
5345 argv is a list or tuple of strings and env is a dictionary
5346 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005347
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5349 PyUnicode_FSConverter,
5350 &opath, &argv, &env))
5351 return NULL;
5352 path = PyBytes_AsString(opath);
5353 if (PyList_Check(argv)) {
5354 argc = PyList_Size(argv);
5355 getitem = PyList_GetItem;
5356 }
5357 else if (PyTuple_Check(argv)) {
5358 argc = PyTuple_Size(argv);
5359 getitem = PyTuple_GetItem;
5360 }
5361 else {
5362 PyErr_SetString(PyExc_TypeError,
5363 "spawnvpe() arg 2 must be a tuple or list");
5364 goto fail_0;
5365 }
5366 if (!PyMapping_Check(env)) {
5367 PyErr_SetString(PyExc_TypeError,
5368 "spawnvpe() arg 3 must be a mapping object");
5369 goto fail_0;
5370 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005371
Victor Stinner8c62be82010-05-06 00:08:46 +00005372 argvlist = PyMem_NEW(char *, argc+1);
5373 if (argvlist == NULL) {
5374 PyErr_NoMemory();
5375 goto fail_0;
5376 }
5377 for (i = 0; i < argc; i++) {
5378 if (!fsconvert_strdup((*getitem)(argv, i),
5379 &argvlist[i]))
5380 {
5381 lastarg = i;
5382 goto fail_1;
5383 }
5384 }
5385 lastarg = argc;
5386 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005387
Victor Stinner8c62be82010-05-06 00:08:46 +00005388 envlist = parse_envlist(env, &envc);
5389 if (envlist == NULL)
5390 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005391
Victor Stinner8c62be82010-05-06 00:08:46 +00005392 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005393#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005394 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005395#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005396 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005397#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005399
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 if (spawnval == -1)
5401 (void) posix_error();
5402 else
5403 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005404
Victor Stinner8c62be82010-05-06 00:08:46 +00005405 while (--envc >= 0)
5406 PyMem_DEL(envlist[envc]);
5407 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005408 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005409 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005410 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005411 Py_DECREF(opath);
5412 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005413}
5414#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005415#endif /* HAVE_SPAWNV */
5416
5417
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005418#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005419PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005420"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005421Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5422\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005423Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005424
5425static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005426posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005427{
Victor Stinner8c62be82010-05-06 00:08:46 +00005428 pid_t pid;
5429 int result = 0;
5430 _PyImport_AcquireLock();
5431 pid = fork1();
5432 if (pid == 0) {
5433 /* child: this clobbers and resets the import lock. */
5434 PyOS_AfterFork();
5435 } else {
5436 /* parent: release the import lock. */
5437 result = _PyImport_ReleaseLock();
5438 }
5439 if (pid == -1)
5440 return posix_error();
5441 if (result < 0) {
5442 /* Don't clobber the OSError if the fork failed. */
5443 PyErr_SetString(PyExc_RuntimeError,
5444 "not holding the import lock");
5445 return NULL;
5446 }
5447 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005448}
5449#endif
5450
5451
Guido van Rossumad0ee831995-03-01 10:34:45 +00005452#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005453PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005454"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005455Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005456Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005457
Barry Warsaw53699e91996-12-10 23:23:01 +00005458static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005459posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005460{
Victor Stinner8c62be82010-05-06 00:08:46 +00005461 pid_t pid;
5462 int result = 0;
5463 _PyImport_AcquireLock();
5464 pid = fork();
5465 if (pid == 0) {
5466 /* child: this clobbers and resets the import lock. */
5467 PyOS_AfterFork();
5468 } else {
5469 /* parent: release the import lock. */
5470 result = _PyImport_ReleaseLock();
5471 }
5472 if (pid == -1)
5473 return posix_error();
5474 if (result < 0) {
5475 /* Don't clobber the OSError if the fork failed. */
5476 PyErr_SetString(PyExc_RuntimeError,
5477 "not holding the import lock");
5478 return NULL;
5479 }
5480 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005481}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005482#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005483
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005484#ifdef HAVE_SCHED_H
5485
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005486#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5487
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005488PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5489"sched_get_priority_max(policy)\n\n\
5490Get the maximum scheduling priority for *policy*.");
5491
5492static PyObject *
5493posix_sched_get_priority_max(PyObject *self, PyObject *args)
5494{
5495 int policy, max;
5496
5497 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5498 return NULL;
5499 max = sched_get_priority_max(policy);
5500 if (max < 0)
5501 return posix_error();
5502 return PyLong_FromLong(max);
5503}
5504
5505PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5506"sched_get_priority_min(policy)\n\n\
5507Get the minimum scheduling priority for *policy*.");
5508
5509static PyObject *
5510posix_sched_get_priority_min(PyObject *self, PyObject *args)
5511{
5512 int policy, min;
5513
5514 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5515 return NULL;
5516 min = sched_get_priority_min(policy);
5517 if (min < 0)
5518 return posix_error();
5519 return PyLong_FromLong(min);
5520}
5521
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005522#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5523
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005524#ifdef HAVE_SCHED_SETSCHEDULER
5525
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005526PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5527"sched_getscheduler(pid)\n\n\
5528Get the scheduling policy for the process with a PID of *pid*.\n\
5529Passing a PID of 0 returns the scheduling policy for the calling process.");
5530
5531static PyObject *
5532posix_sched_getscheduler(PyObject *self, PyObject *args)
5533{
5534 pid_t pid;
5535 int policy;
5536
5537 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5538 return NULL;
5539 policy = sched_getscheduler(pid);
5540 if (policy < 0)
5541 return posix_error();
5542 return PyLong_FromLong(policy);
5543}
5544
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005545#endif
5546
5547#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5548
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005549static PyObject *
5550sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5551{
5552 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005553 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005554
5555 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5556 return NULL;
5557 res = PyStructSequence_New(type);
5558 if (!res)
5559 return NULL;
5560 Py_INCREF(priority);
5561 PyStructSequence_SET_ITEM(res, 0, priority);
5562 return res;
5563}
5564
5565PyDoc_STRVAR(sched_param__doc__,
5566"sched_param(sched_priority): A scheduling parameter.\n\n\
5567Current has only one field: sched_priority");
5568
5569static PyStructSequence_Field sched_param_fields[] = {
5570 {"sched_priority", "the scheduling priority"},
5571 {0}
5572};
5573
5574static PyStructSequence_Desc sched_param_desc = {
5575 "sched_param", /* name */
5576 sched_param__doc__, /* doc */
5577 sched_param_fields,
5578 1
5579};
5580
5581static int
5582convert_sched_param(PyObject *param, struct sched_param *res)
5583{
5584 long priority;
5585
5586 if (Py_TYPE(param) != &SchedParamType) {
5587 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5588 return 0;
5589 }
5590 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5591 if (priority == -1 && PyErr_Occurred())
5592 return 0;
5593 if (priority > INT_MAX || priority < INT_MIN) {
5594 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5595 return 0;
5596 }
5597 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5598 return 1;
5599}
5600
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005601#endif
5602
5603#ifdef HAVE_SCHED_SETSCHEDULER
5604
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005605PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5606"sched_setscheduler(pid, policy, param)\n\n\
5607Set the scheduling policy, *policy*, for *pid*.\n\
5608If *pid* is 0, the calling process is changed.\n\
5609*param* is an instance of sched_param.");
5610
5611static PyObject *
5612posix_sched_setscheduler(PyObject *self, PyObject *args)
5613{
5614 pid_t pid;
5615 int policy;
5616 struct sched_param param;
5617
5618 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5619 &pid, &policy, &convert_sched_param, &param))
5620 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005621
5622 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005623 ** sched_setscheduler() returns 0 in Linux, but the previous
5624 ** scheduling policy under Solaris/Illumos, and others.
5625 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005626 */
5627 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005628 return posix_error();
5629 Py_RETURN_NONE;
5630}
5631
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005632#endif
5633
5634#ifdef HAVE_SCHED_SETPARAM
5635
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005636PyDoc_STRVAR(posix_sched_getparam__doc__,
5637"sched_getparam(pid) -> sched_param\n\n\
5638Returns scheduling parameters for the process with *pid* as an instance of the\n\
5639sched_param class. A PID of 0 means the calling process.");
5640
5641static PyObject *
5642posix_sched_getparam(PyObject *self, PyObject *args)
5643{
5644 pid_t pid;
5645 struct sched_param param;
5646 PyObject *res, *priority;
5647
5648 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5649 return NULL;
5650 if (sched_getparam(pid, &param))
5651 return posix_error();
5652 res = PyStructSequence_New(&SchedParamType);
5653 if (!res)
5654 return NULL;
5655 priority = PyLong_FromLong(param.sched_priority);
5656 if (!priority) {
5657 Py_DECREF(res);
5658 return NULL;
5659 }
5660 PyStructSequence_SET_ITEM(res, 0, priority);
5661 return res;
5662}
5663
5664PyDoc_STRVAR(posix_sched_setparam__doc__,
5665"sched_setparam(pid, param)\n\n\
5666Set scheduling parameters for a process with PID *pid*.\n\
5667A PID of 0 means the calling process.");
5668
5669static PyObject *
5670posix_sched_setparam(PyObject *self, PyObject *args)
5671{
5672 pid_t pid;
5673 struct sched_param param;
5674
5675 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5676 &pid, &convert_sched_param, &param))
5677 return NULL;
5678 if (sched_setparam(pid, &param))
5679 return posix_error();
5680 Py_RETURN_NONE;
5681}
5682
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005683#endif
5684
5685#ifdef HAVE_SCHED_RR_GET_INTERVAL
5686
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005687PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5688"sched_rr_get_interval(pid) -> float\n\n\
5689Return the round-robin quantum for the process with PID *pid* in seconds.");
5690
5691static PyObject *
5692posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5693{
5694 pid_t pid;
5695 struct timespec interval;
5696
5697 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5698 return NULL;
5699 if (sched_rr_get_interval(pid, &interval))
5700 return posix_error();
5701 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5702}
5703
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005704#endif
5705
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005706PyDoc_STRVAR(posix_sched_yield__doc__,
5707"sched_yield()\n\n\
5708Voluntarily relinquish the CPU.");
5709
5710static PyObject *
5711posix_sched_yield(PyObject *self, PyObject *noargs)
5712{
5713 if (sched_yield())
5714 return posix_error();
5715 Py_RETURN_NONE;
5716}
5717
Benjamin Peterson2740af82011-08-02 17:41:34 -05005718#ifdef HAVE_SCHED_SETAFFINITY
5719
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005720typedef struct {
5721 PyObject_HEAD;
5722 Py_ssize_t size;
5723 int ncpus;
5724 cpu_set_t *set;
5725} Py_cpu_set;
5726
5727static PyTypeObject cpu_set_type;
5728
5729static void
5730cpu_set_dealloc(Py_cpu_set *set)
5731{
5732 assert(set->set);
5733 CPU_FREE(set->set);
5734 Py_TYPE(set)->tp_free(set);
5735}
5736
5737static Py_cpu_set *
5738make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
5739{
5740 Py_cpu_set *set;
5741
5742 if (size < 0) {
5743 PyErr_SetString(PyExc_ValueError, "negative size");
5744 return NULL;
5745 }
5746 set = (Py_cpu_set *)type->tp_alloc(type, 0);
5747 if (!set)
5748 return NULL;
5749 set->ncpus = size;
5750 set->size = CPU_ALLOC_SIZE(size);
5751 set->set = CPU_ALLOC(size);
5752 if (!set->set) {
5753 type->tp_free(set);
5754 PyErr_NoMemory();
5755 return NULL;
5756 }
5757 CPU_ZERO_S(set->size, set->set);
5758 return set;
5759}
5760
5761static PyObject *
5762cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5763{
5764 int size;
5765
5766 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
5767 !PyArg_ParseTuple(args, "i:cpu_set", &size))
5768 return NULL;
5769 return (PyObject *)make_new_cpu_set(type, size);
5770}
5771
5772static PyObject *
5773cpu_set_repr(Py_cpu_set *set)
5774{
5775 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02005776}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005777
5778static Py_ssize_t
5779cpu_set_len(Py_cpu_set *set)
5780{
5781 return set->ncpus;
5782}
5783
5784static int
5785_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
5786{
5787 int cpu;
5788 if (!PyArg_ParseTuple(args, requester, &cpu))
5789 return -1;
5790 if (cpu < 0) {
5791 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
5792 return -1;
5793 }
5794 if (cpu >= set->ncpus) {
5795 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
5796 return -1;
5797 }
5798 return cpu;
5799}
5800
5801PyDoc_STRVAR(cpu_set_set_doc,
5802"cpu_set.set(i)\n\n\
5803Add CPU *i* to the set.");
5804
5805static PyObject *
5806cpu_set_set(Py_cpu_set *set, PyObject *args)
5807{
5808 int cpu = _get_cpu(set, "i|set", args);
5809 if (cpu == -1)
5810 return NULL;
5811 CPU_SET_S(cpu, set->size, set->set);
5812 Py_RETURN_NONE;
5813}
5814
5815PyDoc_STRVAR(cpu_set_count_doc,
5816"cpu_set.count() -> int\n\n\
5817Return the number of CPUs active in the set.");
5818
5819static PyObject *
5820cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5821{
5822 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5823}
5824
5825PyDoc_STRVAR(cpu_set_clear_doc,
5826"cpu_set.clear(i)\n\n\
5827Remove CPU *i* from the set.");
5828
5829static PyObject *
5830cpu_set_clear(Py_cpu_set *set, PyObject *args)
5831{
5832 int cpu = _get_cpu(set, "i|clear", args);
5833 if (cpu == -1)
5834 return NULL;
5835 CPU_CLR_S(cpu, set->size, set->set);
5836 Py_RETURN_NONE;
5837}
5838
5839PyDoc_STRVAR(cpu_set_isset_doc,
5840"cpu_set.isset(i) -> bool\n\n\
5841Test if CPU *i* is in the set.");
5842
5843static PyObject *
5844cpu_set_isset(Py_cpu_set *set, PyObject *args)
5845{
5846 int cpu = _get_cpu(set, "i|isset", args);
5847 if (cpu == -1)
5848 return NULL;
5849 if (CPU_ISSET_S(cpu, set->size, set->set))
5850 Py_RETURN_TRUE;
5851 Py_RETURN_FALSE;
5852}
5853
5854PyDoc_STRVAR(cpu_set_zero_doc,
5855"cpu_set.zero()\n\n\
5856Clear the cpu_set.");
5857
5858static PyObject *
5859cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5860{
5861 CPU_ZERO_S(set->size, set->set);
5862 Py_RETURN_NONE;
5863}
5864
5865static PyObject *
5866cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5867{
5868 int eq;
5869
Brian Curtindfc80e32011-08-10 20:28:54 -05005870 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5871 Py_RETURN_NOTIMPLEMENTED;
5872
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005873 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5874 if ((op == Py_EQ) ? eq : !eq)
5875 Py_RETURN_TRUE;
5876 else
5877 Py_RETURN_FALSE;
5878}
5879
5880#define CPU_SET_BINOP(name, op) \
5881 static PyObject * \
5882 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5883 if (res) { \
5884 Py_INCREF(res); \
5885 } \
5886 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005887 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005888 if (!res) \
5889 return NULL; \
5890 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005891 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005892 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005893 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005894 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005895 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005896 op(res->size, res->set, left->set, right->set); \
5897 return (PyObject *)res; \
5898 } \
5899 static PyObject * \
5900 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5901 return do_cpu_set_##name(left, right, NULL); \
5902 } \
5903 static PyObject * \
5904 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5905 return do_cpu_set_##name(left, right, left); \
5906 } \
5907
5908CPU_SET_BINOP(and, CPU_AND_S)
5909CPU_SET_BINOP(or, CPU_OR_S)
5910CPU_SET_BINOP(xor, CPU_XOR_S)
5911#undef CPU_SET_BINOP
5912
5913PyDoc_STRVAR(cpu_set_doc,
5914"cpu_set(size)\n\n\
5915Create an empty mask of CPUs.");
5916
5917static PyNumberMethods cpu_set_as_number = {
5918 0, /*nb_add*/
5919 0, /*nb_subtract*/
5920 0, /*nb_multiply*/
5921 0, /*nb_remainder*/
5922 0, /*nb_divmod*/
5923 0, /*nb_power*/
5924 0, /*nb_negative*/
5925 0, /*nb_positive*/
5926 0, /*nb_absolute*/
5927 0, /*nb_bool*/
5928 0, /*nb_invert*/
5929 0, /*nb_lshift*/
5930 0, /*nb_rshift*/
5931 (binaryfunc)cpu_set_and, /*nb_and*/
5932 (binaryfunc)cpu_set_xor, /*nb_xor*/
5933 (binaryfunc)cpu_set_or, /*nb_or*/
5934 0, /*nb_int*/
5935 0, /*nb_reserved*/
5936 0, /*nb_float*/
5937 0, /*nb_inplace_add*/
5938 0, /*nb_inplace_subtract*/
5939 0, /*nb_inplace_multiply*/
5940 0, /*nb_inplace_remainder*/
5941 0, /*nb_inplace_power*/
5942 0, /*nb_inplace_lshift*/
5943 0, /*nb_inplace_rshift*/
5944 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5945 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5946 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5947};
5948
5949static PySequenceMethods cpu_set_as_sequence = {
5950 (lenfunc)cpu_set_len, /* sq_length */
5951};
5952
5953static PyMethodDef cpu_set_methods[] = {
5954 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5955 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5956 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5957 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5958 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5959 {NULL, NULL} /* sentinel */
5960};
5961
5962static PyTypeObject cpu_set_type = {
5963 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5964 "posix.cpu_set", /* tp_name */
5965 sizeof(Py_cpu_set), /* tp_basicsize */
5966 0, /* tp_itemsize */
5967 /* methods */
5968 (destructor)cpu_set_dealloc, /* tp_dealloc */
5969 0, /* tp_print */
5970 0, /* tp_getattr */
5971 0, /* tp_setattr */
5972 0, /* tp_reserved */
5973 (reprfunc)cpu_set_repr, /* tp_repr */
5974 &cpu_set_as_number, /* tp_as_number */
5975 &cpu_set_as_sequence, /* tp_as_sequence */
5976 0, /* tp_as_mapping */
5977 PyObject_HashNotImplemented, /* tp_hash */
5978 0, /* tp_call */
5979 0, /* tp_str */
5980 PyObject_GenericGetAttr, /* tp_getattro */
5981 0, /* tp_setattro */
5982 0, /* tp_as_buffer */
5983 Py_TPFLAGS_DEFAULT, /* tp_flags */
5984 cpu_set_doc, /* tp_doc */
5985 0, /* tp_traverse */
5986 0, /* tp_clear */
5987 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5988 0, /* tp_weaklistoffset */
5989 0, /* tp_iter */
5990 0, /* tp_iternext */
5991 cpu_set_methods, /* tp_methods */
5992 0, /* tp_members */
5993 0, /* tp_getset */
5994 0, /* tp_base */
5995 0, /* tp_dict */
5996 0, /* tp_descr_get */
5997 0, /* tp_descr_set */
5998 0, /* tp_dictoffset */
5999 0, /* tp_init */
6000 PyType_GenericAlloc, /* tp_alloc */
6001 cpu_set_new, /* tp_new */
6002 PyObject_Del, /* tp_free */
6003};
6004
6005PyDoc_STRVAR(posix_sched_setaffinity__doc__,
6006"sched_setaffinity(pid, cpu_set)\n\n\
6007Set the affinity of the process with PID *pid* to *cpu_set*.");
6008
6009static PyObject *
6010posix_sched_setaffinity(PyObject *self, PyObject *args)
6011{
6012 pid_t pid;
6013 Py_cpu_set *cpu_set;
6014
Benjamin Petersona17a5d62011-08-09 16:49:13 -05006015 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006016 &pid, &cpu_set_type, &cpu_set))
6017 return NULL;
6018 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
6019 return posix_error();
6020 Py_RETURN_NONE;
6021}
6022
6023PyDoc_STRVAR(posix_sched_getaffinity__doc__,
6024"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
6025Return the affinity of the process with PID *pid*.\n\
6026The returned cpu_set will be of size *ncpus*.");
6027
6028static PyObject *
6029posix_sched_getaffinity(PyObject *self, PyObject *args)
6030{
6031 pid_t pid;
6032 int ncpus;
6033 Py_cpu_set *res;
6034
Benjamin Peterson7ac92142011-08-03 08:54:26 -05006035 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006036 &pid, &ncpus))
6037 return NULL;
6038 res = make_new_cpu_set(&cpu_set_type, ncpus);
6039 if (!res)
6040 return NULL;
6041 if (sched_getaffinity(pid, res->size, res->set)) {
6042 Py_DECREF(res);
6043 return posix_error();
6044 }
6045 return (PyObject *)res;
6046}
6047
Benjamin Peterson2740af82011-08-02 17:41:34 -05006048#endif /* HAVE_SCHED_SETAFFINITY */
6049
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006050#endif /* HAVE_SCHED_H */
6051
Neal Norwitzb59798b2003-03-21 01:43:31 +00006052/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006053/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6054#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006055#define DEV_PTY_FILE "/dev/ptc"
6056#define HAVE_DEV_PTMX
6057#else
6058#define DEV_PTY_FILE "/dev/ptmx"
6059#endif
6060
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006061#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006062#ifdef HAVE_PTY_H
6063#include <pty.h>
6064#else
6065#ifdef HAVE_LIBUTIL_H
6066#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006067#else
6068#ifdef HAVE_UTIL_H
6069#include <util.h>
6070#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006071#endif /* HAVE_LIBUTIL_H */
6072#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006073#ifdef HAVE_STROPTS_H
6074#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006075#endif
6076#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006077
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006078#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006080"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006082
6083static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006084posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006085{
Victor Stinner8c62be82010-05-06 00:08:46 +00006086 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006087#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006088 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006089#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006090#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006091 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006092#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006093 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006094#endif
6095#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006096
Thomas Wouters70c21a12000-07-14 14:28:33 +00006097#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006098 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6099 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006100#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006101 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6102 if (slave_name == NULL)
6103 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006104
Victor Stinner8c62be82010-05-06 00:08:46 +00006105 slave_fd = open(slave_name, O_RDWR);
6106 if (slave_fd < 0)
6107 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006108#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6110 if (master_fd < 0)
6111 return posix_error();
6112 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6113 /* change permission of slave */
6114 if (grantpt(master_fd) < 0) {
6115 PyOS_setsig(SIGCHLD, sig_saved);
6116 return posix_error();
6117 }
6118 /* unlock slave */
6119 if (unlockpt(master_fd) < 0) {
6120 PyOS_setsig(SIGCHLD, sig_saved);
6121 return posix_error();
6122 }
6123 PyOS_setsig(SIGCHLD, sig_saved);
6124 slave_name = ptsname(master_fd); /* get name of slave */
6125 if (slave_name == NULL)
6126 return posix_error();
6127 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6128 if (slave_fd < 0)
6129 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006130#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006131 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6132 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006133#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006134 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006135#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006136#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006137#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006138
Victor Stinner8c62be82010-05-06 00:08:46 +00006139 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006140
Fred Drake8cef4cf2000-06-28 16:40:38 +00006141}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006142#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006143
6144#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006145PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006146"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006147Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6148Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006149To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006150
6151static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006152posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006153{
Victor Stinner8c62be82010-05-06 00:08:46 +00006154 int master_fd = -1, result = 0;
6155 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006156
Victor Stinner8c62be82010-05-06 00:08:46 +00006157 _PyImport_AcquireLock();
6158 pid = forkpty(&master_fd, NULL, NULL, NULL);
6159 if (pid == 0) {
6160 /* child: this clobbers and resets the import lock. */
6161 PyOS_AfterFork();
6162 } else {
6163 /* parent: release the import lock. */
6164 result = _PyImport_ReleaseLock();
6165 }
6166 if (pid == -1)
6167 return posix_error();
6168 if (result < 0) {
6169 /* Don't clobber the OSError if the fork failed. */
6170 PyErr_SetString(PyExc_RuntimeError,
6171 "not holding the import lock");
6172 return NULL;
6173 }
6174 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006175}
6176#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006177
Ross Lagerwall7807c352011-03-17 20:20:30 +02006178
Guido van Rossumad0ee831995-03-01 10:34:45 +00006179#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006180PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006181"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006182Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006183
Barry Warsaw53699e91996-12-10 23:23:01 +00006184static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006185posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006186{
Victor Stinner8c62be82010-05-06 00:08:46 +00006187 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006188}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006189#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006191
Guido van Rossumad0ee831995-03-01 10:34:45 +00006192#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006193PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006194"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006195Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006196
Barry Warsaw53699e91996-12-10 23:23:01 +00006197static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006198posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006199{
Victor Stinner8c62be82010-05-06 00:08:46 +00006200 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006201}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006202#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006204
Guido van Rossumad0ee831995-03-01 10:34:45 +00006205#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006206PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006207"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006208Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006209
Barry Warsaw53699e91996-12-10 23:23:01 +00006210static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006211posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006212{
Victor Stinner8c62be82010-05-06 00:08:46 +00006213 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006214}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006215#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006216
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006217
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006218PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006219"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006220Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006221
Barry Warsaw53699e91996-12-10 23:23:01 +00006222static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006223posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006224{
Victor Stinner8c62be82010-05-06 00:08:46 +00006225 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006226}
6227
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006228#ifdef HAVE_GETGROUPLIST
6229PyDoc_STRVAR(posix_getgrouplist__doc__,
6230"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6231Returns a list of groups to which a user belongs.\n\n\
6232 user: username to lookup\n\
6233 group: base group id of the user");
6234
6235static PyObject *
6236posix_getgrouplist(PyObject *self, PyObject *args)
6237{
6238#ifdef NGROUPS_MAX
6239#define MAX_GROUPS NGROUPS_MAX
6240#else
6241 /* defined to be 16 on Solaris7, so this should be a small number */
6242#define MAX_GROUPS 64
6243#endif
6244
6245 const char *user;
6246 int i, ngroups;
6247 PyObject *list;
6248#ifdef __APPLE__
6249 int *groups, basegid;
6250#else
6251 gid_t *groups, basegid;
6252#endif
6253 ngroups = MAX_GROUPS;
6254
6255 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
6256 return NULL;
6257
6258#ifdef __APPLE__
6259 groups = PyMem_Malloc(ngroups * sizeof(int));
6260#else
6261 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6262#endif
6263 if (groups == NULL)
6264 return PyErr_NoMemory();
6265
6266 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6267 PyMem_Del(groups);
6268 return posix_error();
6269 }
6270
6271 list = PyList_New(ngroups);
6272 if (list == NULL) {
6273 PyMem_Del(groups);
6274 return NULL;
6275 }
6276
6277 for (i = 0; i < ngroups; i++) {
6278 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
6279 if (o == NULL) {
6280 Py_DECREF(list);
6281 PyMem_Del(groups);
6282 return NULL;
6283 }
6284 PyList_SET_ITEM(list, i, o);
6285 }
6286
6287 PyMem_Del(groups);
6288
6289 return list;
6290}
6291#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006292
Fred Drakec9680921999-12-13 16:37:25 +00006293#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006294PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006295"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006296Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006297
6298static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006299posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006300{
6301 PyObject *result = NULL;
6302
Fred Drakec9680921999-12-13 16:37:25 +00006303#ifdef NGROUPS_MAX
6304#define MAX_GROUPS NGROUPS_MAX
6305#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006307#define MAX_GROUPS 64
6308#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006309 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006310
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006311 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006312 * This is a helper variable to store the intermediate result when
6313 * that happens.
6314 *
6315 * To keep the code readable the OSX behaviour is unconditional,
6316 * according to the POSIX spec this should be safe on all unix-y
6317 * systems.
6318 */
6319 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006321
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006323 if (n < 0) {
6324 if (errno == EINVAL) {
6325 n = getgroups(0, NULL);
6326 if (n == -1) {
6327 return posix_error();
6328 }
6329 if (n == 0) {
6330 /* Avoid malloc(0) */
6331 alt_grouplist = grouplist;
6332 } else {
6333 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6334 if (alt_grouplist == NULL) {
6335 errno = EINVAL;
6336 return posix_error();
6337 }
6338 n = getgroups(n, alt_grouplist);
6339 if (n == -1) {
6340 PyMem_Free(alt_grouplist);
6341 return posix_error();
6342 }
6343 }
6344 } else {
6345 return posix_error();
6346 }
6347 }
6348 result = PyList_New(n);
6349 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006350 int i;
6351 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006352 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006354 Py_DECREF(result);
6355 result = NULL;
6356 break;
Fred Drakec9680921999-12-13 16:37:25 +00006357 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006359 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006360 }
6361
6362 if (alt_grouplist != grouplist) {
6363 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006365
Fred Drakec9680921999-12-13 16:37:25 +00006366 return result;
6367}
6368#endif
6369
Antoine Pitroub7572f02009-12-02 20:46:48 +00006370#ifdef HAVE_INITGROUPS
6371PyDoc_STRVAR(posix_initgroups__doc__,
6372"initgroups(username, gid) -> None\n\n\
6373Call the system initgroups() to initialize the group access list with all of\n\
6374the groups of which the specified username is a member, plus the specified\n\
6375group id.");
6376
6377static PyObject *
6378posix_initgroups(PyObject *self, PyObject *args)
6379{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006380 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006382 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006384
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006385 if (!PyArg_ParseTuple(args, "O&l:initgroups",
6386 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006388 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006389
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006390 res = initgroups(username, (gid_t) gid);
6391 Py_DECREF(oname);
6392 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006394
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 Py_INCREF(Py_None);
6396 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006397}
6398#endif
6399
Martin v. Löwis606edc12002-06-13 21:09:11 +00006400#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006401PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006402"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006403Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006404
6405static PyObject *
6406posix_getpgid(PyObject *self, PyObject *args)
6407{
Victor Stinner8c62be82010-05-06 00:08:46 +00006408 pid_t pid, pgid;
6409 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6410 return NULL;
6411 pgid = getpgid(pid);
6412 if (pgid < 0)
6413 return posix_error();
6414 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006415}
6416#endif /* HAVE_GETPGID */
6417
6418
Guido van Rossumb6775db1994-08-01 11:34:53 +00006419#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006420PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006421"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006422Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006423
Barry Warsaw53699e91996-12-10 23:23:01 +00006424static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006425posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006426{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006427#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006429#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006431#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006432}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006433#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006434
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006435
Guido van Rossumb6775db1994-08-01 11:34:53 +00006436#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006437PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006438"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006439Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006440
Barry Warsaw53699e91996-12-10 23:23:01 +00006441static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006442posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006443{
Guido van Rossum64933891994-10-20 21:56:42 +00006444#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006446#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006447 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006448#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 return posix_error();
6450 Py_INCREF(Py_None);
6451 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006452}
6453
Guido van Rossumb6775db1994-08-01 11:34:53 +00006454#endif /* HAVE_SETPGRP */
6455
Guido van Rossumad0ee831995-03-01 10:34:45 +00006456#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006457
6458#ifdef MS_WINDOWS
6459#include <tlhelp32.h>
6460
6461static PyObject*
6462win32_getppid()
6463{
6464 HANDLE snapshot;
6465 pid_t mypid;
6466 PyObject* result = NULL;
6467 BOOL have_record;
6468 PROCESSENTRY32 pe;
6469
6470 mypid = getpid(); /* This function never fails */
6471
6472 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6473 if (snapshot == INVALID_HANDLE_VALUE)
6474 return PyErr_SetFromWindowsErr(GetLastError());
6475
6476 pe.dwSize = sizeof(pe);
6477 have_record = Process32First(snapshot, &pe);
6478 while (have_record) {
6479 if (mypid == (pid_t)pe.th32ProcessID) {
6480 /* We could cache the ulong value in a static variable. */
6481 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6482 break;
6483 }
6484
6485 have_record = Process32Next(snapshot, &pe);
6486 }
6487
6488 /* If our loop exits and our pid was not found (result will be NULL)
6489 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6490 * error anyway, so let's raise it. */
6491 if (!result)
6492 result = PyErr_SetFromWindowsErr(GetLastError());
6493
6494 CloseHandle(snapshot);
6495
6496 return result;
6497}
6498#endif /*MS_WINDOWS*/
6499
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006500PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006501"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006502Return the parent's process id. If the parent process has already exited,\n\
6503Windows machines will still return its id; others systems will return the id\n\
6504of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006505
Barry Warsaw53699e91996-12-10 23:23:01 +00006506static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006507posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006508{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006509#ifdef MS_WINDOWS
6510 return win32_getppid();
6511#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006512 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006513#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006514}
6515#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006517
Fred Drake12c6e2d1999-12-14 21:25:03 +00006518#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006519PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006520"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006521Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006522
6523static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006524posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006525{
Victor Stinner8c62be82010-05-06 00:08:46 +00006526 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006527#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006528 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006529 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006530
6531 if (GetUserNameW(user_name, &num_chars)) {
6532 /* num_chars is the number of unicode chars plus null terminator */
6533 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006534 }
6535 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006536 result = PyErr_SetFromWindowsErr(GetLastError());
6537#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006538 char *name;
6539 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006540
Victor Stinner8c62be82010-05-06 00:08:46 +00006541 errno = 0;
6542 name = getlogin();
6543 if (name == NULL) {
6544 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006545 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006546 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006547 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 }
6549 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006550 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006552#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006553 return result;
6554}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006555#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006556
Guido van Rossumad0ee831995-03-01 10:34:45 +00006557#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006558PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006559"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006560Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006561
Barry Warsaw53699e91996-12-10 23:23:01 +00006562static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006563posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006564{
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006566}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006567#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006568
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006569
Guido van Rossumad0ee831995-03-01 10:34:45 +00006570#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006571PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006572"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006573Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006574
Barry Warsaw53699e91996-12-10 23:23:01 +00006575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006576posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006577{
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 pid_t pid;
6579 int sig;
6580 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6581 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006582#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006583 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6584 APIRET rc;
6585 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006586 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006587
6588 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6589 APIRET rc;
6590 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006591 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006592
6593 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006594 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006595#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 if (kill(pid, sig) == -1)
6597 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006598#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 Py_INCREF(Py_None);
6600 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006601}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006602#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006603
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006604#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006605PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006606"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006607Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006608
6609static PyObject *
6610posix_killpg(PyObject *self, PyObject *args)
6611{
Victor Stinner8c62be82010-05-06 00:08:46 +00006612 int sig;
6613 pid_t pgid;
6614 /* XXX some man pages make the `pgid` parameter an int, others
6615 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6616 take the same type. Moreover, pid_t is always at least as wide as
6617 int (else compilation of this module fails), which is safe. */
6618 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6619 return NULL;
6620 if (killpg(pgid, sig) == -1)
6621 return posix_error();
6622 Py_INCREF(Py_None);
6623 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006624}
6625#endif
6626
Brian Curtineb24d742010-04-12 17:16:38 +00006627#ifdef MS_WINDOWS
6628PyDoc_STRVAR(win32_kill__doc__,
6629"kill(pid, sig)\n\n\
6630Kill a process with a signal.");
6631
6632static PyObject *
6633win32_kill(PyObject *self, PyObject *args)
6634{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006635 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006636 DWORD pid, sig, err;
6637 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006638
Victor Stinner8c62be82010-05-06 00:08:46 +00006639 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6640 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006641
Victor Stinner8c62be82010-05-06 00:08:46 +00006642 /* Console processes which share a common console can be sent CTRL+C or
6643 CTRL+BREAK events, provided they handle said events. */
6644 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6645 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6646 err = GetLastError();
6647 PyErr_SetFromWindowsErr(err);
6648 }
6649 else
6650 Py_RETURN_NONE;
6651 }
Brian Curtineb24d742010-04-12 17:16:38 +00006652
Victor Stinner8c62be82010-05-06 00:08:46 +00006653 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6654 attempt to open and terminate the process. */
6655 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6656 if (handle == NULL) {
6657 err = GetLastError();
6658 return PyErr_SetFromWindowsErr(err);
6659 }
Brian Curtineb24d742010-04-12 17:16:38 +00006660
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 if (TerminateProcess(handle, sig) == 0) {
6662 err = GetLastError();
6663 result = PyErr_SetFromWindowsErr(err);
6664 } else {
6665 Py_INCREF(Py_None);
6666 result = Py_None;
6667 }
Brian Curtineb24d742010-04-12 17:16:38 +00006668
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 CloseHandle(handle);
6670 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006671}
6672#endif /* MS_WINDOWS */
6673
Guido van Rossumc0125471996-06-28 18:55:32 +00006674#ifdef HAVE_PLOCK
6675
6676#ifdef HAVE_SYS_LOCK_H
6677#include <sys/lock.h>
6678#endif
6679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006680PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006681"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006682Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006683
Barry Warsaw53699e91996-12-10 23:23:01 +00006684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006685posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006686{
Victor Stinner8c62be82010-05-06 00:08:46 +00006687 int op;
6688 if (!PyArg_ParseTuple(args, "i:plock", &op))
6689 return NULL;
6690 if (plock(op) == -1)
6691 return posix_error();
6692 Py_INCREF(Py_None);
6693 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006694}
6695#endif
6696
Guido van Rossumb6775db1994-08-01 11:34:53 +00006697#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006698PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006699"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006700Set the current process's user id.");
6701
Barry Warsaw53699e91996-12-10 23:23:01 +00006702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006703posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006704{
Victor Stinner8c62be82010-05-06 00:08:46 +00006705 long uid_arg;
6706 uid_t uid;
6707 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6708 return NULL;
6709 uid = uid_arg;
6710 if (uid != uid_arg) {
6711 PyErr_SetString(PyExc_OverflowError, "user id too big");
6712 return NULL;
6713 }
6714 if (setuid(uid) < 0)
6715 return posix_error();
6716 Py_INCREF(Py_None);
6717 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006718}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006719#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006720
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006721
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006722#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006723PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006724"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006725Set the current process's effective user id.");
6726
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006727static PyObject *
6728posix_seteuid (PyObject *self, PyObject *args)
6729{
Victor Stinner8c62be82010-05-06 00:08:46 +00006730 long euid_arg;
6731 uid_t euid;
6732 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6733 return NULL;
6734 euid = euid_arg;
6735 if (euid != euid_arg) {
6736 PyErr_SetString(PyExc_OverflowError, "user id too big");
6737 return NULL;
6738 }
6739 if (seteuid(euid) < 0) {
6740 return posix_error();
6741 } else {
6742 Py_INCREF(Py_None);
6743 return Py_None;
6744 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006745}
6746#endif /* HAVE_SETEUID */
6747
6748#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006749PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006750"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006751Set the current process's effective group id.");
6752
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006753static PyObject *
6754posix_setegid (PyObject *self, PyObject *args)
6755{
Victor Stinner8c62be82010-05-06 00:08:46 +00006756 long egid_arg;
6757 gid_t egid;
6758 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6759 return NULL;
6760 egid = egid_arg;
6761 if (egid != egid_arg) {
6762 PyErr_SetString(PyExc_OverflowError, "group id too big");
6763 return NULL;
6764 }
6765 if (setegid(egid) < 0) {
6766 return posix_error();
6767 } else {
6768 Py_INCREF(Py_None);
6769 return Py_None;
6770 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006771}
6772#endif /* HAVE_SETEGID */
6773
6774#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006775PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006776"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006777Set the current process's real and effective user ids.");
6778
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006779static PyObject *
6780posix_setreuid (PyObject *self, PyObject *args)
6781{
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 long ruid_arg, euid_arg;
6783 uid_t ruid, euid;
6784 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6785 return NULL;
6786 if (ruid_arg == -1)
6787 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6788 else
6789 ruid = ruid_arg; /* otherwise, assign from our long */
6790 if (euid_arg == -1)
6791 euid = (uid_t)-1;
6792 else
6793 euid = euid_arg;
6794 if ((euid_arg != -1 && euid != euid_arg) ||
6795 (ruid_arg != -1 && ruid != ruid_arg)) {
6796 PyErr_SetString(PyExc_OverflowError, "user id too big");
6797 return NULL;
6798 }
6799 if (setreuid(ruid, euid) < 0) {
6800 return posix_error();
6801 } else {
6802 Py_INCREF(Py_None);
6803 return Py_None;
6804 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006805}
6806#endif /* HAVE_SETREUID */
6807
6808#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006809PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006810"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006811Set the current process's real and effective group ids.");
6812
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006813static PyObject *
6814posix_setregid (PyObject *self, PyObject *args)
6815{
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 long rgid_arg, egid_arg;
6817 gid_t rgid, egid;
6818 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6819 return NULL;
6820 if (rgid_arg == -1)
6821 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6822 else
6823 rgid = rgid_arg; /* otherwise, assign from our long */
6824 if (egid_arg == -1)
6825 egid = (gid_t)-1;
6826 else
6827 egid = egid_arg;
6828 if ((egid_arg != -1 && egid != egid_arg) ||
6829 (rgid_arg != -1 && rgid != rgid_arg)) {
6830 PyErr_SetString(PyExc_OverflowError, "group id too big");
6831 return NULL;
6832 }
6833 if (setregid(rgid, egid) < 0) {
6834 return posix_error();
6835 } else {
6836 Py_INCREF(Py_None);
6837 return Py_None;
6838 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006839}
6840#endif /* HAVE_SETREGID */
6841
Guido van Rossumb6775db1994-08-01 11:34:53 +00006842#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006843PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006844"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006845Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006846
Barry Warsaw53699e91996-12-10 23:23:01 +00006847static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006848posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006849{
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 long gid_arg;
6851 gid_t gid;
6852 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6853 return NULL;
6854 gid = gid_arg;
6855 if (gid != gid_arg) {
6856 PyErr_SetString(PyExc_OverflowError, "group id too big");
6857 return NULL;
6858 }
6859 if (setgid(gid) < 0)
6860 return posix_error();
6861 Py_INCREF(Py_None);
6862 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006863}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006864#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006865
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006866#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006867PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006868"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006869Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006870
6871static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006872posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006873{
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 int i, len;
6875 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006876
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 if (!PySequence_Check(groups)) {
6878 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6879 return NULL;
6880 }
6881 len = PySequence_Size(groups);
6882 if (len > MAX_GROUPS) {
6883 PyErr_SetString(PyExc_ValueError, "too many groups");
6884 return NULL;
6885 }
6886 for(i = 0; i < len; i++) {
6887 PyObject *elem;
6888 elem = PySequence_GetItem(groups, i);
6889 if (!elem)
6890 return NULL;
6891 if (!PyLong_Check(elem)) {
6892 PyErr_SetString(PyExc_TypeError,
6893 "groups must be integers");
6894 Py_DECREF(elem);
6895 return NULL;
6896 } else {
6897 unsigned long x = PyLong_AsUnsignedLong(elem);
6898 if (PyErr_Occurred()) {
6899 PyErr_SetString(PyExc_TypeError,
6900 "group id too big");
6901 Py_DECREF(elem);
6902 return NULL;
6903 }
6904 grouplist[i] = x;
6905 /* read back the value to see if it fitted in gid_t */
6906 if (grouplist[i] != x) {
6907 PyErr_SetString(PyExc_TypeError,
6908 "group id too big");
6909 Py_DECREF(elem);
6910 return NULL;
6911 }
6912 }
6913 Py_DECREF(elem);
6914 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006915
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 if (setgroups(len, grouplist) < 0)
6917 return posix_error();
6918 Py_INCREF(Py_None);
6919 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006920}
6921#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006922
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006923#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6924static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006925wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006926{
Victor Stinner8c62be82010-05-06 00:08:46 +00006927 PyObject *result;
6928 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006929 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006930
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 if (pid == -1)
6932 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006933
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 if (struct_rusage == NULL) {
6935 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6936 if (m == NULL)
6937 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006938 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006939 Py_DECREF(m);
6940 if (struct_rusage == NULL)
6941 return NULL;
6942 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006943
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6945 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6946 if (!result)
6947 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006948
6949#ifndef doubletime
6950#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6951#endif
6952
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006954 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006956 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006957#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6959 SET_INT(result, 2, ru->ru_maxrss);
6960 SET_INT(result, 3, ru->ru_ixrss);
6961 SET_INT(result, 4, ru->ru_idrss);
6962 SET_INT(result, 5, ru->ru_isrss);
6963 SET_INT(result, 6, ru->ru_minflt);
6964 SET_INT(result, 7, ru->ru_majflt);
6965 SET_INT(result, 8, ru->ru_nswap);
6966 SET_INT(result, 9, ru->ru_inblock);
6967 SET_INT(result, 10, ru->ru_oublock);
6968 SET_INT(result, 11, ru->ru_msgsnd);
6969 SET_INT(result, 12, ru->ru_msgrcv);
6970 SET_INT(result, 13, ru->ru_nsignals);
6971 SET_INT(result, 14, ru->ru_nvcsw);
6972 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006973#undef SET_INT
6974
Victor Stinner8c62be82010-05-06 00:08:46 +00006975 if (PyErr_Occurred()) {
6976 Py_DECREF(result);
6977 return NULL;
6978 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006979
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006981}
6982#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6983
6984#ifdef HAVE_WAIT3
6985PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006986"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006987Wait for completion of a child process.");
6988
6989static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006990posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006991{
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 pid_t pid;
6993 int options;
6994 struct rusage ru;
6995 WAIT_TYPE status;
6996 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006997
Victor Stinner4195b5c2012-02-08 23:03:19 +01006998 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006999 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007000
Victor Stinner8c62be82010-05-06 00:08:46 +00007001 Py_BEGIN_ALLOW_THREADS
7002 pid = wait3(&status, options, &ru);
7003 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007004
Victor Stinner4195b5c2012-02-08 23:03:19 +01007005 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007006}
7007#endif /* HAVE_WAIT3 */
7008
7009#ifdef HAVE_WAIT4
7010PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007011"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007012Wait for completion of a given child process.");
7013
7014static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007015posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007016{
Victor Stinner8c62be82010-05-06 00:08:46 +00007017 pid_t pid;
7018 int options;
7019 struct rusage ru;
7020 WAIT_TYPE status;
7021 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007022
Victor Stinner4195b5c2012-02-08 23:03:19 +01007023 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007025
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 Py_BEGIN_ALLOW_THREADS
7027 pid = wait4(pid, &status, options, &ru);
7028 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007029
Victor Stinner4195b5c2012-02-08 23:03:19 +01007030 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007031}
7032#endif /* HAVE_WAIT4 */
7033
Ross Lagerwall7807c352011-03-17 20:20:30 +02007034#if defined(HAVE_WAITID) && !defined(__APPLE__)
7035PyDoc_STRVAR(posix_waitid__doc__,
7036"waitid(idtype, id, options) -> waitid_result\n\n\
7037Wait for the completion of one or more child processes.\n\n\
7038idtype can be P_PID, P_PGID or P_ALL.\n\
7039id specifies the pid to wait on.\n\
7040options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
7041or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
7042Returns either waitid_result or None if WNOHANG is specified and there are\n\
7043no children in a waitable state.");
7044
7045static PyObject *
7046posix_waitid(PyObject *self, PyObject *args)
7047{
7048 PyObject *result;
7049 idtype_t idtype;
7050 id_t id;
7051 int options, res;
7052 siginfo_t si;
7053 si.si_pid = 0;
7054 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
7055 return NULL;
7056 Py_BEGIN_ALLOW_THREADS
7057 res = waitid(idtype, id, &si, options);
7058 Py_END_ALLOW_THREADS
7059 if (res == -1)
7060 return posix_error();
7061
7062 if (si.si_pid == 0)
7063 Py_RETURN_NONE;
7064
7065 result = PyStructSequence_New(&WaitidResultType);
7066 if (!result)
7067 return NULL;
7068
7069 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
7070 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
7071 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7072 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7073 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7074 if (PyErr_Occurred()) {
7075 Py_DECREF(result);
7076 return NULL;
7077 }
7078
7079 return result;
7080}
7081#endif
7082
Guido van Rossumb6775db1994-08-01 11:34:53 +00007083#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007084PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007085"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007086Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007087
Barry Warsaw53699e91996-12-10 23:23:01 +00007088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007089posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007090{
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 pid_t pid;
7092 int options;
7093 WAIT_TYPE status;
7094 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007095
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7097 return NULL;
7098 Py_BEGIN_ALLOW_THREADS
7099 pid = waitpid(pid, &status, options);
7100 Py_END_ALLOW_THREADS
7101 if (pid == -1)
7102 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007103
Victor Stinner8c62be82010-05-06 00:08:46 +00007104 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007105}
7106
Tim Petersab034fa2002-02-01 11:27:43 +00007107#elif defined(HAVE_CWAIT)
7108
7109/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007110PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007111"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007112"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007113
7114static PyObject *
7115posix_waitpid(PyObject *self, PyObject *args)
7116{
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 Py_intptr_t pid;
7118 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007119
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7121 return NULL;
7122 Py_BEGIN_ALLOW_THREADS
7123 pid = _cwait(&status, pid, options);
7124 Py_END_ALLOW_THREADS
7125 if (pid == -1)
7126 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007127
Victor Stinner8c62be82010-05-06 00:08:46 +00007128 /* shift the status left a byte so this is more like the POSIX waitpid */
7129 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007130}
7131#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007132
Guido van Rossumad0ee831995-03-01 10:34:45 +00007133#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007134PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007135"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007136Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007137
Barry Warsaw53699e91996-12-10 23:23:01 +00007138static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007139posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007140{
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 pid_t pid;
7142 WAIT_TYPE status;
7143 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007144
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 Py_BEGIN_ALLOW_THREADS
7146 pid = wait(&status);
7147 Py_END_ALLOW_THREADS
7148 if (pid == -1)
7149 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007150
Victor Stinner8c62be82010-05-06 00:08:46 +00007151 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007152}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007153#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007155
Larry Hastings9cf065c2012-06-22 16:30:09 -07007156#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7157PyDoc_STRVAR(readlink__doc__,
7158"readlink(path, *, dir_fd=None) -> path\n\n\
7159Return a string representing the path to which the symbolic link points.\n\
7160\n\
7161If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7162 and path should be relative; path will then be relative to that directory.\n\
7163dir_fd may not be implemented on your platform.\n\
7164 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007165#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007166
Guido van Rossumb6775db1994-08-01 11:34:53 +00007167#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007168
Barry Warsaw53699e91996-12-10 23:23:01 +00007169static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007171{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007172 path_t path;
7173 int dir_fd = DEFAULT_DIR_FD;
7174 char buffer[MAXPATHLEN];
7175 ssize_t length;
7176 PyObject *return_value = NULL;
7177 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007178
Larry Hastings9cf065c2012-06-22 16:30:09 -07007179 memset(&path, 0, sizeof(path));
7180 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7181 path_converter, &path,
7182#ifdef HAVE_READLINKAT
7183 dir_fd_converter, &dir_fd
7184#else
7185 dir_fd_unavailable, &dir_fd
7186#endif
7187 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007188 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007189
Victor Stinner8c62be82010-05-06 00:08:46 +00007190 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007191#ifdef HAVE_READLINKAT
7192 if (dir_fd != DEFAULT_DIR_FD)
7193 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007194 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007195#endif
7196 length = readlink(path.narrow, buffer, sizeof(buffer));
7197 Py_END_ALLOW_THREADS
7198
7199 if (length < 0) {
7200 return_value = path_posix_error("readlink", &path);
7201 goto exit;
7202 }
7203
7204 if (PyUnicode_Check(path.object))
7205 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7206 else
7207 return_value = PyBytes_FromStringAndSize(buffer, length);
7208exit:
7209 path_cleanup(&path);
7210 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007211}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007212
7213
Guido van Rossumb6775db1994-08-01 11:34:53 +00007214#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007216
Larry Hastings9cf065c2012-06-22 16:30:09 -07007217#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007218PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007219"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7220Create a symbolic link pointing to src named dst.\n\n\
7221target_is_directory is required on Windows if the target is to be\n\
7222 interpreted as a directory. (On Windows, symlink requires\n\
7223 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7224 target_is_directory is ignored on non-Windows platforms.\n\
7225\n\
7226If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7227 and path should be relative; path will then be relative to that directory.\n\
7228dir_fd may not be implemented on your platform.\n\
7229 If it is unavailable, using it will raise a NotImplementedError.");
7230
7231#if defined(MS_WINDOWS)
7232
7233/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7234static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7235static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7236static int
7237check_CreateSymbolicLink()
7238{
7239 HINSTANCE hKernel32;
7240 /* only recheck */
7241 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7242 return 1;
7243 hKernel32 = GetModuleHandleW(L"KERNEL32");
7244 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7245 "CreateSymbolicLinkW");
7246 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7247 "CreateSymbolicLinkA");
7248 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7249}
7250
7251#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007252
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007253static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007254posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007255{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007256 path_t src;
7257 path_t dst;
7258 int dir_fd = DEFAULT_DIR_FD;
7259 int target_is_directory = 0;
7260 static char *keywords[] = {"src", "dst", "target_is_directory",
7261 "dir_fd", NULL};
7262 PyObject *return_value;
7263#ifdef MS_WINDOWS
7264 DWORD result;
7265#else
7266 int result;
7267#endif
7268
7269 memset(&src, 0, sizeof(src));
7270 src.argument_name = "src";
7271 memset(&dst, 0, sizeof(dst));
7272 dst.argument_name = "dst";
7273
7274#ifdef MS_WINDOWS
7275 if (!check_CreateSymbolicLink()) {
7276 PyErr_SetString(PyExc_NotImplementedError,
7277 "CreateSymbolicLink functions not found");
7278 return NULL;
7279 }
7280 if (!win32_can_symlink) {
7281 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
7282 return NULL;
7283 }
7284#endif
7285
7286 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7287 keywords,
7288 path_converter, &src,
7289 path_converter, &dst,
7290 &target_is_directory,
7291#ifdef HAVE_SYMLINKAT
7292 dir_fd_converter, &dir_fd
7293#else
7294 dir_fd_unavailable, &dir_fd
7295#endif
7296 ))
7297 return NULL;
7298
7299 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7300 PyErr_SetString(PyExc_ValueError,
7301 "symlink: src and dst must be the same type");
7302 return_value = NULL;
7303 goto exit;
7304 }
7305
7306#ifdef MS_WINDOWS
7307 Py_BEGIN_ALLOW_THREADS
7308 if (dst.wide)
7309 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7310 target_is_directory);
7311 else
7312 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7313 target_is_directory);
7314 Py_END_ALLOW_THREADS
7315
7316 if (!result) {
7317 return_value = win32_error_object("symlink", src.object);
7318 goto exit;
7319 }
7320
7321#else
7322
7323 Py_BEGIN_ALLOW_THREADS
7324#if HAVE_SYMLINKAT
7325 if (dir_fd != DEFAULT_DIR_FD)
7326 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7327 else
7328#endif
7329 result = symlink(src.narrow, dst.narrow);
7330 Py_END_ALLOW_THREADS
7331
7332 if (result) {
7333 return_value = path_error("symlink", &dst);
7334 goto exit;
7335 }
7336#endif
7337
7338 return_value = Py_None;
7339 Py_INCREF(Py_None);
7340 goto exit; /* silence "unused label" warning */
7341exit:
7342 path_cleanup(&src);
7343 path_cleanup(&dst);
7344 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007345}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007346
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007347#endif /* HAVE_SYMLINK */
7348
Larry Hastings9cf065c2012-06-22 16:30:09 -07007349
Brian Curtind40e6f72010-07-08 21:39:08 +00007350#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7351
Brian Curtind40e6f72010-07-08 21:39:08 +00007352static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007353win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007354{
7355 wchar_t *path;
7356 DWORD n_bytes_returned;
7357 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007358 PyObject *po, *result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007359 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007360 HANDLE reparse_point_handle;
7361
7362 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7363 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7364 wchar_t *print_name;
7365
Larry Hastings9cf065c2012-06-22 16:30:09 -07007366 static char *keywords[] = {"path", "dir_fd", NULL};
7367
7368 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7369 &po,
7370 dir_fd_unavailable, &dir_fd
7371 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007372 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007373
Victor Stinnereb5657a2011-09-30 01:44:27 +02007374 path = PyUnicode_AsUnicode(po);
7375 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007376 return NULL;
7377
7378 /* First get a handle to the reparse point */
7379 Py_BEGIN_ALLOW_THREADS
7380 reparse_point_handle = CreateFileW(
7381 path,
7382 0,
7383 0,
7384 0,
7385 OPEN_EXISTING,
7386 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7387 0);
7388 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007389
Brian Curtind40e6f72010-07-08 21:39:08 +00007390 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007391 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007392
Brian Curtind40e6f72010-07-08 21:39:08 +00007393 Py_BEGIN_ALLOW_THREADS
7394 /* New call DeviceIoControl to read the reparse point */
7395 io_result = DeviceIoControl(
7396 reparse_point_handle,
7397 FSCTL_GET_REPARSE_POINT,
7398 0, 0, /* in buffer */
7399 target_buffer, sizeof(target_buffer),
7400 &n_bytes_returned,
7401 0 /* we're not using OVERLAPPED_IO */
7402 );
7403 CloseHandle(reparse_point_handle);
7404 Py_END_ALLOW_THREADS
7405
7406 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007407 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007408
7409 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7410 {
7411 PyErr_SetString(PyExc_ValueError,
7412 "not a symbolic link");
7413 return NULL;
7414 }
Brian Curtin74e45612010-07-09 15:58:59 +00007415 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7416 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7417
7418 result = PyUnicode_FromWideChar(print_name,
7419 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007420 return result;
7421}
7422
7423#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7424
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007425
Larry Hastings605a62d2012-06-24 04:33:36 -07007426static PyStructSequence_Field times_result_fields[] = {
7427 {"user", "user time"},
7428 {"system", "system time"},
7429 {"children_user", "user time of children"},
7430 {"children_system", "system time of children"},
7431 {"elapsed", "elapsed time since an arbitrary point in the past"},
7432 {NULL}
7433};
7434
7435PyDoc_STRVAR(times_result__doc__,
7436"times_result: Result from os.times().\n\n\
7437This object may be accessed either as a tuple of\n\
7438 (user, system, children_user, children_system, elapsed),\n\
7439or via the attributes user, system, children_user, children_system,\n\
7440and elapsed.\n\
7441\n\
7442See os.times for more information.");
7443
7444static PyStructSequence_Desc times_result_desc = {
7445 "times_result", /* name */
7446 times_result__doc__, /* doc */
7447 times_result_fields,
7448 5
7449};
7450
7451static PyTypeObject TimesResultType;
7452
7453
7454#if defined(HAVE_TIMES) || defined(MS_WINDOWS)
7455
7456static PyObject *
7457build_times_result(double user, double system,
7458 double children_user, double children_system,
7459 double elapsed)
7460{
7461 PyObject *value = PyStructSequence_New(&TimesResultType);
7462 if (value == NULL)
7463 return NULL;
7464
7465#define SET(i, field) \
7466 { \
7467 PyObject *o = PyFloat_FromDouble(field); \
7468 if (!o) { \
7469 Py_DECREF(value); \
7470 return NULL; \
7471 } \
7472 PyStructSequence_SET_ITEM(value, i, o); \
7473 } \
7474
7475 SET(0, user);
7476 SET(1, system);
7477 SET(2, children_user);
7478 SET(3, children_system);
7479 SET(4, elapsed);
7480
7481#undef SET
7482
7483 return value;
7484}
7485
7486PyDoc_STRVAR(posix_times__doc__,
7487"times() -> times_result\n\n\
7488Return an object containing floating point numbers indicating process\n\
7489times. The object behaves like a named tuple with these fields:\n\
7490 (utime, stime, cutime, cstime, elapsed_time)");
7491
7492#endif
7493
7494
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007495#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00007496#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7497static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007498system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007499{
7500 ULONG value = 0;
7501
7502 Py_BEGIN_ALLOW_THREADS
7503 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7504 Py_END_ALLOW_THREADS
7505
7506 return value;
7507}
7508
7509static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007510posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007511{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007512 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007513 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007514 (double)0 /* t.tms_utime / HZ */,
7515 (double)0 /* t.tms_stime / HZ */,
7516 (double)0 /* t.tms_cutime / HZ */,
7517 (double)0 /* t.tms_cstime / HZ */,
7518 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007519}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007520#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007521#define NEED_TICKS_PER_SECOND
7522static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00007523static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007524posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00007525{
Victor Stinner8c62be82010-05-06 00:08:46 +00007526 struct tms t;
7527 clock_t c;
7528 errno = 0;
7529 c = times(&t);
7530 if (c == (clock_t) -1)
7531 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07007532 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007533 (double)t.tms_utime / ticks_per_second,
7534 (double)t.tms_stime / ticks_per_second,
7535 (double)t.tms_cutime / ticks_per_second,
7536 (double)t.tms_cstime / ticks_per_second,
7537 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00007538}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007539#endif /* not OS2 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007540#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007541static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007542posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007543{
Victor Stinner8c62be82010-05-06 00:08:46 +00007544 FILETIME create, exit, kernel, user;
7545 HANDLE hProc;
7546 hProc = GetCurrentProcess();
7547 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7548 /* The fields of a FILETIME structure are the hi and lo part
7549 of a 64-bit value expressed in 100 nanosecond units.
7550 1e7 is one second in such units; 1e-7 the inverse.
7551 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7552 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007553 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007554 (double)(user.dwHighDateTime*429.4967296 +
7555 user.dwLowDateTime*1e-7),
7556 (double)(kernel.dwHighDateTime*429.4967296 +
7557 kernel.dwLowDateTime*1e-7),
7558 (double)0,
7559 (double)0,
7560 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007561}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007562#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007563
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007564
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007565#ifdef HAVE_GETSID
7566PyDoc_STRVAR(posix_getsid__doc__,
7567"getsid(pid) -> sid\n\n\
7568Call the system call getsid().");
7569
7570static PyObject *
7571posix_getsid(PyObject *self, PyObject *args)
7572{
Victor Stinner8c62be82010-05-06 00:08:46 +00007573 pid_t pid;
7574 int sid;
7575 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7576 return NULL;
7577 sid = getsid(pid);
7578 if (sid < 0)
7579 return posix_error();
7580 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007581}
7582#endif /* HAVE_GETSID */
7583
7584
Guido van Rossumb6775db1994-08-01 11:34:53 +00007585#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007586PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007587"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007588Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007589
Barry Warsaw53699e91996-12-10 23:23:01 +00007590static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007591posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007592{
Victor Stinner8c62be82010-05-06 00:08:46 +00007593 if (setsid() < 0)
7594 return posix_error();
7595 Py_INCREF(Py_None);
7596 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007597}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007598#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007599
Guido van Rossumb6775db1994-08-01 11:34:53 +00007600#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007601PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007602"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007603Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007604
Barry Warsaw53699e91996-12-10 23:23:01 +00007605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007606posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007607{
Victor Stinner8c62be82010-05-06 00:08:46 +00007608 pid_t pid;
7609 int pgrp;
7610 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7611 return NULL;
7612 if (setpgid(pid, pgrp) < 0)
7613 return posix_error();
7614 Py_INCREF(Py_None);
7615 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007616}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007617#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007618
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007619
Guido van Rossumb6775db1994-08-01 11:34:53 +00007620#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007621PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007622"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007623Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007624
Barry Warsaw53699e91996-12-10 23:23:01 +00007625static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007626posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007627{
Victor Stinner8c62be82010-05-06 00:08:46 +00007628 int fd;
7629 pid_t pgid;
7630 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7631 return NULL;
7632 pgid = tcgetpgrp(fd);
7633 if (pgid < 0)
7634 return posix_error();
7635 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007636}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007637#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007638
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007639
Guido van Rossumb6775db1994-08-01 11:34:53 +00007640#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007641PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007642"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007643Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007644
Barry Warsaw53699e91996-12-10 23:23:01 +00007645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007646posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007647{
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 int fd;
7649 pid_t pgid;
7650 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7651 return NULL;
7652 if (tcsetpgrp(fd, pgid) < 0)
7653 return posix_error();
7654 Py_INCREF(Py_None);
7655 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007656}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007657#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007658
Guido van Rossum687dd131993-05-17 08:34:16 +00007659/* Functions acting on file descriptors */
7660
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007661PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007662"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7663Open a file for low level IO. Returns a file handle (integer).\n\
7664\n\
7665If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7666 and path should be relative; path will then be relative to that directory.\n\
7667dir_fd may not be implemented on your platform.\n\
7668 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007669
Barry Warsaw53699e91996-12-10 23:23:01 +00007670static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007671posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007672{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007673 path_t path;
7674 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007675 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007676 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007678 PyObject *return_value = NULL;
7679 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007680
Larry Hastings9cf065c2012-06-22 16:30:09 -07007681 memset(&path, 0, sizeof(path));
7682 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7683 path_converter, &path,
7684 &flags, &mode,
7685#ifdef HAVE_OPENAT
7686 dir_fd_converter, &dir_fd
7687#else
7688 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007689#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007690 ))
7691 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007692
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007694#ifdef MS_WINDOWS
7695 if (path.wide)
7696 fd = _wopen(path.wide, flags, mode);
7697 else
7698#endif
7699#ifdef HAVE_OPENAT
7700 if (dir_fd != DEFAULT_DIR_FD)
7701 fd = openat(dir_fd, path.narrow, flags, mode);
7702 else
7703#endif
7704 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007706
Larry Hastings9cf065c2012-06-22 16:30:09 -07007707 if (fd == -1) {
7708#ifdef MS_WINDOWS
7709 /* force use of posix_error here for exact backwards compatibility */
7710 if (path.wide)
7711 return_value = posix_error();
7712 else
7713#endif
7714 return_value = path_error("open", &path);
7715 goto exit;
7716 }
7717
7718 return_value = PyLong_FromLong((long)fd);
7719
7720exit:
7721 path_cleanup(&path);
7722 return return_value;
7723}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007724
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007725PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007726"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007727Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007728
Barry Warsaw53699e91996-12-10 23:23:01 +00007729static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007730posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007731{
Victor Stinner8c62be82010-05-06 00:08:46 +00007732 int fd, res;
7733 if (!PyArg_ParseTuple(args, "i:close", &fd))
7734 return NULL;
7735 if (!_PyVerify_fd(fd))
7736 return posix_error();
7737 Py_BEGIN_ALLOW_THREADS
7738 res = close(fd);
7739 Py_END_ALLOW_THREADS
7740 if (res < 0)
7741 return posix_error();
7742 Py_INCREF(Py_None);
7743 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007744}
7745
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007746
Victor Stinner8c62be82010-05-06 00:08:46 +00007747PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007748"closerange(fd_low, fd_high)\n\n\
7749Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7750
7751static PyObject *
7752posix_closerange(PyObject *self, PyObject *args)
7753{
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 int fd_from, fd_to, i;
7755 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7756 return NULL;
7757 Py_BEGIN_ALLOW_THREADS
7758 for (i = fd_from; i < fd_to; i++)
7759 if (_PyVerify_fd(i))
7760 close(i);
7761 Py_END_ALLOW_THREADS
7762 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007763}
7764
7765
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007766PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007767"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007768Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007769
Barry Warsaw53699e91996-12-10 23:23:01 +00007770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007771posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007772{
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 int fd;
7774 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7775 return NULL;
7776 if (!_PyVerify_fd(fd))
7777 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 if (fd < 0)
7780 return posix_error();
7781 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007782}
7783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007784
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007785PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007786"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007787Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007788
Barry Warsaw53699e91996-12-10 23:23:01 +00007789static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007790posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007791{
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 int fd, fd2, res;
7793 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7794 return NULL;
7795 if (!_PyVerify_fd_dup2(fd, fd2))
7796 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 if (res < 0)
7799 return posix_error();
7800 Py_INCREF(Py_None);
7801 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007802}
7803
Ross Lagerwall7807c352011-03-17 20:20:30 +02007804#ifdef HAVE_LOCKF
7805PyDoc_STRVAR(posix_lockf__doc__,
7806"lockf(fd, cmd, len)\n\n\
7807Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7808fd is an open file descriptor.\n\
7809cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7810F_TEST.\n\
7811len specifies the section of the file to lock.");
7812
7813static PyObject *
7814posix_lockf(PyObject *self, PyObject *args)
7815{
7816 int fd, cmd, res;
7817 off_t len;
7818 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7819 &fd, &cmd, _parse_off_t, &len))
7820 return NULL;
7821
7822 Py_BEGIN_ALLOW_THREADS
7823 res = lockf(fd, cmd, len);
7824 Py_END_ALLOW_THREADS
7825
7826 if (res < 0)
7827 return posix_error();
7828
7829 Py_RETURN_NONE;
7830}
7831#endif
7832
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007833
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007834PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007835"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007836Set the current position of a file descriptor.\n\
7837Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007838
Barry Warsaw53699e91996-12-10 23:23:01 +00007839static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007840posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007841{
Victor Stinner8c62be82010-05-06 00:08:46 +00007842 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007843#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007845#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007847#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007848 PyObject *posobj;
7849 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007850 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007851#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7853 switch (how) {
7854 case 0: how = SEEK_SET; break;
7855 case 1: how = SEEK_CUR; break;
7856 case 2: how = SEEK_END; break;
7857 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007858#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007859
Ross Lagerwall8e749672011-03-17 21:54:07 +02007860#if !defined(HAVE_LARGEFILE_SUPPORT)
7861 pos = PyLong_AsLong(posobj);
7862#else
7863 pos = PyLong_AsLongLong(posobj);
7864#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007865 if (PyErr_Occurred())
7866 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007867
Victor Stinner8c62be82010-05-06 00:08:46 +00007868 if (!_PyVerify_fd(fd))
7869 return posix_error();
7870 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007871#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007873#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007875#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 Py_END_ALLOW_THREADS
7877 if (res < 0)
7878 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007879
7880#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007882#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007883 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007884#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007885}
7886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007887
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007888PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007889"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007890Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007891
Barry Warsaw53699e91996-12-10 23:23:01 +00007892static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007893posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007894{
Victor Stinner8c62be82010-05-06 00:08:46 +00007895 int fd, size;
7896 Py_ssize_t n;
7897 PyObject *buffer;
7898 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7899 return NULL;
7900 if (size < 0) {
7901 errno = EINVAL;
7902 return posix_error();
7903 }
7904 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7905 if (buffer == NULL)
7906 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007907 if (!_PyVerify_fd(fd)) {
7908 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007909 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007910 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007911 Py_BEGIN_ALLOW_THREADS
7912 n = read(fd, PyBytes_AS_STRING(buffer), size);
7913 Py_END_ALLOW_THREADS
7914 if (n < 0) {
7915 Py_DECREF(buffer);
7916 return posix_error();
7917 }
7918 if (n != size)
7919 _PyBytes_Resize(&buffer, n);
7920 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007921}
7922
Ross Lagerwall7807c352011-03-17 20:20:30 +02007923#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7924 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007925static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007926iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7927{
7928 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007929 Py_ssize_t blen, total = 0;
7930
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007931 *iov = PyMem_New(struct iovec, cnt);
7932 if (*iov == NULL) {
7933 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007934 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007935 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007936
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007937 *buf = PyMem_New(Py_buffer, cnt);
7938 if (*buf == NULL) {
7939 PyMem_Del(*iov);
7940 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007941 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007942 }
7943
7944 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007945 PyObject *item = PySequence_GetItem(seq, i);
7946 if (item == NULL)
7947 goto fail;
7948 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7949 Py_DECREF(item);
7950 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007951 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007952 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007953 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007954 blen = (*buf)[i].len;
7955 (*iov)[i].iov_len = blen;
7956 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007957 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007958 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007959
7960fail:
7961 PyMem_Del(*iov);
7962 for (j = 0; j < i; j++) {
7963 PyBuffer_Release(&(*buf)[j]);
7964 }
7965 PyMem_Del(*buf);
7966 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007967}
7968
7969static void
7970iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7971{
7972 int i;
7973 PyMem_Del(iov);
7974 for (i = 0; i < cnt; i++) {
7975 PyBuffer_Release(&buf[i]);
7976 }
7977 PyMem_Del(buf);
7978}
7979#endif
7980
Ross Lagerwall7807c352011-03-17 20:20:30 +02007981#ifdef HAVE_READV
7982PyDoc_STRVAR(posix_readv__doc__,
7983"readv(fd, buffers) -> bytesread\n\n\
7984Read from a file descriptor into a number of writable buffers. buffers\n\
7985is an arbitrary sequence of writable buffers.\n\
7986Returns the total number of bytes read.");
7987
7988static PyObject *
7989posix_readv(PyObject *self, PyObject *args)
7990{
7991 int fd, cnt;
7992 Py_ssize_t n;
7993 PyObject *seq;
7994 struct iovec *iov;
7995 Py_buffer *buf;
7996
7997 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7998 return NULL;
7999 if (!PySequence_Check(seq)) {
8000 PyErr_SetString(PyExc_TypeError,
8001 "readv() arg 2 must be a sequence");
8002 return NULL;
8003 }
8004 cnt = PySequence_Size(seq);
8005
8006 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
8007 return NULL;
8008
8009 Py_BEGIN_ALLOW_THREADS
8010 n = readv(fd, iov, cnt);
8011 Py_END_ALLOW_THREADS
8012
8013 iov_cleanup(iov, buf, cnt);
8014 return PyLong_FromSsize_t(n);
8015}
8016#endif
8017
8018#ifdef HAVE_PREAD
8019PyDoc_STRVAR(posix_pread__doc__,
8020"pread(fd, buffersize, offset) -> string\n\n\
8021Read from a file descriptor, fd, at a position of offset. It will read up\n\
8022to buffersize number of bytes. The file offset remains unchanged.");
8023
8024static PyObject *
8025posix_pread(PyObject *self, PyObject *args)
8026{
8027 int fd, size;
8028 off_t offset;
8029 Py_ssize_t n;
8030 PyObject *buffer;
8031 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8032 return NULL;
8033
8034 if (size < 0) {
8035 errno = EINVAL;
8036 return posix_error();
8037 }
8038 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8039 if (buffer == NULL)
8040 return NULL;
8041 if (!_PyVerify_fd(fd)) {
8042 Py_DECREF(buffer);
8043 return posix_error();
8044 }
8045 Py_BEGIN_ALLOW_THREADS
8046 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8047 Py_END_ALLOW_THREADS
8048 if (n < 0) {
8049 Py_DECREF(buffer);
8050 return posix_error();
8051 }
8052 if (n != size)
8053 _PyBytes_Resize(&buffer, n);
8054 return buffer;
8055}
8056#endif
8057
8058PyDoc_STRVAR(posix_write__doc__,
8059"write(fd, string) -> byteswritten\n\n\
8060Write a string to a file descriptor.");
8061
8062static PyObject *
8063posix_write(PyObject *self, PyObject *args)
8064{
8065 Py_buffer pbuf;
8066 int fd;
8067 Py_ssize_t size, len;
8068
8069 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8070 return NULL;
8071 if (!_PyVerify_fd(fd)) {
8072 PyBuffer_Release(&pbuf);
8073 return posix_error();
8074 }
8075 len = pbuf.len;
8076 Py_BEGIN_ALLOW_THREADS
8077#if defined(MS_WIN64) || defined(MS_WINDOWS)
8078 if (len > INT_MAX)
8079 len = INT_MAX;
8080 size = write(fd, pbuf.buf, (int)len);
8081#else
8082 size = write(fd, pbuf.buf, len);
8083#endif
8084 Py_END_ALLOW_THREADS
8085 PyBuffer_Release(&pbuf);
8086 if (size < 0)
8087 return posix_error();
8088 return PyLong_FromSsize_t(size);
8089}
8090
8091#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008092PyDoc_STRVAR(posix_sendfile__doc__,
8093"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8094sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8095 -> byteswritten\n\
8096Copy nbytes bytes from file descriptor in to file descriptor out.");
8097
8098static PyObject *
8099posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8100{
8101 int in, out;
8102 Py_ssize_t ret;
8103 off_t offset;
8104
8105#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8106#ifndef __APPLE__
8107 Py_ssize_t len;
8108#endif
8109 PyObject *headers = NULL, *trailers = NULL;
8110 Py_buffer *hbuf, *tbuf;
8111 off_t sbytes;
8112 struct sf_hdtr sf;
8113 int flags = 0;
8114 sf.headers = NULL;
8115 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008116 static char *keywords[] = {"out", "in",
8117 "offset", "count",
8118 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008119
8120#ifdef __APPLE__
8121 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008122 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008123#else
8124 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008125 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008126#endif
8127 &headers, &trailers, &flags))
8128 return NULL;
8129 if (headers != NULL) {
8130 if (!PySequence_Check(headers)) {
8131 PyErr_SetString(PyExc_TypeError,
8132 "sendfile() headers must be a sequence or None");
8133 return NULL;
8134 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008135 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008136 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008137 if (sf.hdr_cnt > 0 &&
8138 !(i = iov_setup(&(sf.headers), &hbuf,
8139 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008140 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008141#ifdef __APPLE__
8142 sbytes += i;
8143#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008144 }
8145 }
8146 if (trailers != NULL) {
8147 if (!PySequence_Check(trailers)) {
8148 PyErr_SetString(PyExc_TypeError,
8149 "sendfile() trailers must be a sequence or None");
8150 return NULL;
8151 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008152 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008153 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008154 if (sf.trl_cnt > 0 &&
8155 !(i = iov_setup(&(sf.trailers), &tbuf,
8156 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008157 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008158#ifdef __APPLE__
8159 sbytes += i;
8160#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008161 }
8162 }
8163
8164 Py_BEGIN_ALLOW_THREADS
8165#ifdef __APPLE__
8166 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8167#else
8168 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8169#endif
8170 Py_END_ALLOW_THREADS
8171
8172 if (sf.headers != NULL)
8173 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8174 if (sf.trailers != NULL)
8175 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8176
8177 if (ret < 0) {
8178 if ((errno == EAGAIN) || (errno == EBUSY)) {
8179 if (sbytes != 0) {
8180 // some data has been sent
8181 goto done;
8182 }
8183 else {
8184 // no data has been sent; upper application is supposed
8185 // to retry on EAGAIN or EBUSY
8186 return posix_error();
8187 }
8188 }
8189 return posix_error();
8190 }
8191 goto done;
8192
8193done:
8194 #if !defined(HAVE_LARGEFILE_SUPPORT)
8195 return Py_BuildValue("l", sbytes);
8196 #else
8197 return Py_BuildValue("L", sbytes);
8198 #endif
8199
8200#else
8201 Py_ssize_t count;
8202 PyObject *offobj;
8203 static char *keywords[] = {"out", "in",
8204 "offset", "count", NULL};
8205 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8206 keywords, &out, &in, &offobj, &count))
8207 return NULL;
8208#ifdef linux
8209 if (offobj == Py_None) {
8210 Py_BEGIN_ALLOW_THREADS
8211 ret = sendfile(out, in, NULL, count);
8212 Py_END_ALLOW_THREADS
8213 if (ret < 0)
8214 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008215 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008216 }
8217#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008218 if (!_parse_off_t(offobj, &offset))
8219 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008220 Py_BEGIN_ALLOW_THREADS
8221 ret = sendfile(out, in, &offset, count);
8222 Py_END_ALLOW_THREADS
8223 if (ret < 0)
8224 return posix_error();
8225 return Py_BuildValue("n", ret);
8226#endif
8227}
8228#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008229
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008230PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008231"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008232Like stat(), but for an open file descriptor.\n\
8233Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008234
Barry Warsaw53699e91996-12-10 23:23:01 +00008235static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008236posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008237{
Victor Stinner8c62be82010-05-06 00:08:46 +00008238 int fd;
8239 STRUCT_STAT st;
8240 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008241 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008242 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008243#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008244 /* on OpenVMS we must ensure that all bytes are written to the file */
8245 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008246#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 if (!_PyVerify_fd(fd))
8248 return posix_error();
8249 Py_BEGIN_ALLOW_THREADS
8250 res = FSTAT(fd, &st);
8251 Py_END_ALLOW_THREADS
8252 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008253#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008254 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008255#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008257#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008258 }
Tim Peters5aa91602002-01-30 05:46:57 +00008259
Victor Stinner4195b5c2012-02-08 23:03:19 +01008260 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008261}
8262
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008263PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008264"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008265Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008266connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008267
8268static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008269posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008270{
Victor Stinner8c62be82010-05-06 00:08:46 +00008271 int fd;
8272 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8273 return NULL;
8274 if (!_PyVerify_fd(fd))
8275 return PyBool_FromLong(0);
8276 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008277}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008278
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008279#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008280PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008281"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008282Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008283
Barry Warsaw53699e91996-12-10 23:23:01 +00008284static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008285posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008286{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008287#if defined(PYOS_OS2)
8288 HFILE read, write;
8289 APIRET rc;
8290
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008291 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008292 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008293 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008294
8295 return Py_BuildValue("(ii)", read, write);
8296#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008297#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008298 int fds[2];
8299 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008300 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008301 if (res != 0)
8302 return posix_error();
8303 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008304#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008305 HANDLE read, write;
8306 int read_fd, write_fd;
8307 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008308 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008309 if (!ok)
8310 return win32_error("CreatePipe", NULL);
8311 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8312 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8313 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008314#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008315#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008316}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008317#endif /* HAVE_PIPE */
8318
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008319#ifdef HAVE_PIPE2
8320PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008321"pipe2(flags) -> (read_end, write_end)\n\n\
8322Create a pipe with flags set atomically.\n\
8323flags can be constructed by ORing together one or more of these values:\n\
8324O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008325");
8326
8327static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008328posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008329{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008330 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008331 int fds[2];
8332 int res;
8333
Charles-François Natali368f34b2011-06-06 19:49:47 +02008334 flags = PyLong_AsLong(arg);
8335 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008336 return NULL;
8337
8338 res = pipe2(fds, flags);
8339 if (res != 0)
8340 return posix_error();
8341 return Py_BuildValue("(ii)", fds[0], fds[1]);
8342}
8343#endif /* HAVE_PIPE2 */
8344
Ross Lagerwall7807c352011-03-17 20:20:30 +02008345#ifdef HAVE_WRITEV
8346PyDoc_STRVAR(posix_writev__doc__,
8347"writev(fd, buffers) -> byteswritten\n\n\
8348Write the contents of buffers to a file descriptor, where buffers is an\n\
8349arbitrary sequence of buffers.\n\
8350Returns the total bytes written.");
8351
8352static PyObject *
8353posix_writev(PyObject *self, PyObject *args)
8354{
8355 int fd, cnt;
8356 Py_ssize_t res;
8357 PyObject *seq;
8358 struct iovec *iov;
8359 Py_buffer *buf;
8360 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8361 return NULL;
8362 if (!PySequence_Check(seq)) {
8363 PyErr_SetString(PyExc_TypeError,
8364 "writev() arg 2 must be a sequence");
8365 return NULL;
8366 }
8367 cnt = PySequence_Size(seq);
8368
8369 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8370 return NULL;
8371 }
8372
8373 Py_BEGIN_ALLOW_THREADS
8374 res = writev(fd, iov, cnt);
8375 Py_END_ALLOW_THREADS
8376
8377 iov_cleanup(iov, buf, cnt);
8378 return PyLong_FromSsize_t(res);
8379}
8380#endif
8381
8382#ifdef HAVE_PWRITE
8383PyDoc_STRVAR(posix_pwrite__doc__,
8384"pwrite(fd, string, offset) -> byteswritten\n\n\
8385Write string to a file descriptor, fd, from offset, leaving the file\n\
8386offset unchanged.");
8387
8388static PyObject *
8389posix_pwrite(PyObject *self, PyObject *args)
8390{
8391 Py_buffer pbuf;
8392 int fd;
8393 off_t offset;
8394 Py_ssize_t size;
8395
8396 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8397 return NULL;
8398
8399 if (!_PyVerify_fd(fd)) {
8400 PyBuffer_Release(&pbuf);
8401 return posix_error();
8402 }
8403 Py_BEGIN_ALLOW_THREADS
8404 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8405 Py_END_ALLOW_THREADS
8406 PyBuffer_Release(&pbuf);
8407 if (size < 0)
8408 return posix_error();
8409 return PyLong_FromSsize_t(size);
8410}
8411#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008412
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008413#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008414PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008415"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8416Create a FIFO (a POSIX named pipe).\n\
8417\n\
8418If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8419 and path should be relative; path will then be relative to that directory.\n\
8420dir_fd may not be implemented on your platform.\n\
8421 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008422
Barry Warsaw53699e91996-12-10 23:23:01 +00008423static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008424posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008425{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008426 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008427 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008428 int dir_fd = DEFAULT_DIR_FD;
8429 int result;
8430 PyObject *return_value = NULL;
8431 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8432
8433 memset(&path, 0, sizeof(path));
8434 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8435 path_converter, &path,
8436 &mode,
8437#ifdef HAVE_MKFIFOAT
8438 dir_fd_converter, &dir_fd
8439#else
8440 dir_fd_unavailable, &dir_fd
8441#endif
8442 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008443 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008444
Victor Stinner8c62be82010-05-06 00:08:46 +00008445 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008446#ifdef HAVE_MKFIFOAT
8447 if (dir_fd != DEFAULT_DIR_FD)
8448 result = mkfifoat(dir_fd, path.narrow, mode);
8449 else
8450#endif
8451 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008452 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008453
8454 if (result < 0) {
8455 return_value = posix_error();
8456 goto exit;
8457 }
8458
8459 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008460 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008461
8462exit:
8463 path_cleanup(&path);
8464 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008465}
8466#endif
8467
Neal Norwitz11690112002-07-30 01:08:28 +00008468#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008469PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008470"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008471Create a filesystem node (file, device special file or named pipe)\n\
8472named filename. mode specifies both the permissions to use and the\n\
8473type of node to be created, being combined (bitwise OR) with one of\n\
8474S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008475device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008476os.makedev()), otherwise it is ignored.\n\
8477\n\
8478If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8479 and path should be relative; path will then be relative to that directory.\n\
8480dir_fd may not be implemented on your platform.\n\
8481 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008482
8483
8484static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008485posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008486{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008487 path_t path;
8488 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008489 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008490 int dir_fd = DEFAULT_DIR_FD;
8491 int result;
8492 PyObject *return_value = NULL;
8493 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8494
8495 memset(&path, 0, sizeof(path));
8496 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8497 path_converter, &path,
8498 &mode, &device,
8499#ifdef HAVE_MKNODAT
8500 dir_fd_converter, &dir_fd
8501#else
8502 dir_fd_unavailable, &dir_fd
8503#endif
8504 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008506
Victor Stinner8c62be82010-05-06 00:08:46 +00008507 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008508#ifdef HAVE_MKNODAT
8509 if (dir_fd != DEFAULT_DIR_FD)
8510 result = mknodat(dir_fd, path.narrow, mode, device);
8511 else
8512#endif
8513 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008515
8516 if (result < 0) {
8517 return_value = posix_error();
8518 goto exit;
8519 }
8520
8521 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008522 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008523
Larry Hastings9cf065c2012-06-22 16:30:09 -07008524exit:
8525 path_cleanup(&path);
8526 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008527}
8528#endif
8529
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008530#ifdef HAVE_DEVICE_MACROS
8531PyDoc_STRVAR(posix_major__doc__,
8532"major(device) -> major number\n\
8533Extracts a device major number from a raw device number.");
8534
8535static PyObject *
8536posix_major(PyObject *self, PyObject *args)
8537{
Victor Stinner8c62be82010-05-06 00:08:46 +00008538 int device;
8539 if (!PyArg_ParseTuple(args, "i:major", &device))
8540 return NULL;
8541 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008542}
8543
8544PyDoc_STRVAR(posix_minor__doc__,
8545"minor(device) -> minor number\n\
8546Extracts a device minor number from a raw device number.");
8547
8548static PyObject *
8549posix_minor(PyObject *self, PyObject *args)
8550{
Victor Stinner8c62be82010-05-06 00:08:46 +00008551 int device;
8552 if (!PyArg_ParseTuple(args, "i:minor", &device))
8553 return NULL;
8554 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008555}
8556
8557PyDoc_STRVAR(posix_makedev__doc__,
8558"makedev(major, minor) -> device number\n\
8559Composes a raw device number from the major and minor device numbers.");
8560
8561static PyObject *
8562posix_makedev(PyObject *self, PyObject *args)
8563{
Victor Stinner8c62be82010-05-06 00:08:46 +00008564 int major, minor;
8565 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8566 return NULL;
8567 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008568}
8569#endif /* device macros */
8570
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008571
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008572#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008573PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008574"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008575Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008576
Barry Warsaw53699e91996-12-10 23:23:01 +00008577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008578posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008579{
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 int fd;
8581 off_t length;
8582 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008583
Ross Lagerwall7807c352011-03-17 20:20:30 +02008584 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008585 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008586
Victor Stinner8c62be82010-05-06 00:08:46 +00008587 Py_BEGIN_ALLOW_THREADS
8588 res = ftruncate(fd, length);
8589 Py_END_ALLOW_THREADS
8590 if (res < 0)
8591 return posix_error();
8592 Py_INCREF(Py_None);
8593 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008594}
8595#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008596
Ross Lagerwall7807c352011-03-17 20:20:30 +02008597#ifdef HAVE_TRUNCATE
8598PyDoc_STRVAR(posix_truncate__doc__,
8599"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008600Truncate the file given by path to length bytes.\n\
8601On some platforms, path may also be specified as an open file descriptor.\n\
8602 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008603
8604static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008605posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008606{
Georg Brandl306336b2012-06-24 12:55:33 +02008607 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008608 off_t length;
8609 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008610 PyObject *result = NULL;
8611 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008612
Georg Brandl306336b2012-06-24 12:55:33 +02008613 memset(&path, 0, sizeof(path));
8614#ifdef HAVE_FTRUNCATE
8615 path.allow_fd = 1;
8616#endif
8617 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8618 path_converter, &path,
8619 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008620 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008621
8622 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008623#ifdef HAVE_FTRUNCATE
8624 if (path.fd != -1)
8625 res = ftruncate(path.fd, length);
8626 else
8627#endif
8628 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008629 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008630 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008631 result = path_posix_error("truncate", &path);
8632 else {
8633 Py_INCREF(Py_None);
8634 result = Py_None;
8635 }
8636 path_cleanup(&path);
8637 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008638}
8639#endif
8640
8641#ifdef HAVE_POSIX_FALLOCATE
8642PyDoc_STRVAR(posix_posix_fallocate__doc__,
8643"posix_fallocate(fd, offset, len)\n\n\
8644Ensures that enough disk space is allocated for the file specified by fd\n\
8645starting from offset and continuing for len bytes.");
8646
8647static PyObject *
8648posix_posix_fallocate(PyObject *self, PyObject *args)
8649{
8650 off_t len, offset;
8651 int res, fd;
8652
8653 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8654 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8655 return NULL;
8656
8657 Py_BEGIN_ALLOW_THREADS
8658 res = posix_fallocate(fd, offset, len);
8659 Py_END_ALLOW_THREADS
8660 if (res != 0) {
8661 errno = res;
8662 return posix_error();
8663 }
8664 Py_RETURN_NONE;
8665}
8666#endif
8667
8668#ifdef HAVE_POSIX_FADVISE
8669PyDoc_STRVAR(posix_posix_fadvise__doc__,
8670"posix_fadvise(fd, offset, len, advice)\n\n\
8671Announces an intention to access data in a specific pattern thus allowing\n\
8672the kernel to make optimizations.\n\
8673The advice applies to the region of the file specified by fd starting at\n\
8674offset and continuing for len bytes.\n\
8675advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8676POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8677POSIX_FADV_DONTNEED.");
8678
8679static PyObject *
8680posix_posix_fadvise(PyObject *self, PyObject *args)
8681{
8682 off_t len, offset;
8683 int res, fd, advice;
8684
8685 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8686 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8687 return NULL;
8688
8689 Py_BEGIN_ALLOW_THREADS
8690 res = posix_fadvise(fd, offset, len, advice);
8691 Py_END_ALLOW_THREADS
8692 if (res != 0) {
8693 errno = res;
8694 return posix_error();
8695 }
8696 Py_RETURN_NONE;
8697}
8698#endif
8699
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008700#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008701PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008702"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008703Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008704
Fred Drake762e2061999-08-26 17:23:54 +00008705/* Save putenv() parameters as values here, so we can collect them when they
8706 * get re-set with another call for the same key. */
8707static PyObject *posix_putenv_garbage;
8708
Tim Peters5aa91602002-01-30 05:46:57 +00008709static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008710posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008711{
Victor Stinner84ae1182010-05-06 22:05:07 +00008712 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008713#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008714 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008715 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008716
Victor Stinner8c62be82010-05-06 00:08:46 +00008717 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008718 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008719 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008720 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008721
Victor Stinner65170952011-11-22 22:16:17 +01008722 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008723 if (newstr == NULL) {
8724 PyErr_NoMemory();
8725 goto error;
8726 }
Victor Stinner65170952011-11-22 22:16:17 +01008727 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8728 PyErr_Format(PyExc_ValueError,
8729 "the environment variable is longer than %u characters",
8730 _MAX_ENV);
8731 goto error;
8732 }
8733
Victor Stinner8c62be82010-05-06 00:08:46 +00008734 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008735 if (newenv == NULL)
8736 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008737 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008738 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008739 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008740 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008741#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008742 PyObject *os1, *os2;
8743 char *s1, *s2;
8744 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008745
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008746 if (!PyArg_ParseTuple(args,
8747 "O&O&:putenv",
8748 PyUnicode_FSConverter, &os1,
8749 PyUnicode_FSConverter, &os2))
8750 return NULL;
8751 s1 = PyBytes_AsString(os1);
8752 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008753
Victor Stinner65170952011-11-22 22:16:17 +01008754 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008755 if (newstr == NULL) {
8756 PyErr_NoMemory();
8757 goto error;
8758 }
8759
Victor Stinner8c62be82010-05-06 00:08:46 +00008760 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008761 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008762 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008763 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008764 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008765#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008766
Victor Stinner8c62be82010-05-06 00:08:46 +00008767 /* Install the first arg and newstr in posix_putenv_garbage;
8768 * this will cause previous value to be collected. This has to
8769 * happen after the real putenv() call because the old value
8770 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008771 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 /* really not much we can do; just leak */
8773 PyErr_Clear();
8774 }
8775 else {
8776 Py_DECREF(newstr);
8777 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008778
Martin v. Löwis011e8422009-05-05 04:43:17 +00008779#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008780 Py_DECREF(os1);
8781 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008782#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008783 Py_RETURN_NONE;
8784
8785error:
8786#ifndef MS_WINDOWS
8787 Py_DECREF(os1);
8788 Py_DECREF(os2);
8789#endif
8790 Py_XDECREF(newstr);
8791 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008792}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008793#endif /* putenv */
8794
Guido van Rossumc524d952001-10-19 01:31:59 +00008795#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008796PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008797"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008798Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008799
8800static PyObject *
8801posix_unsetenv(PyObject *self, PyObject *args)
8802{
Victor Stinner65170952011-11-22 22:16:17 +01008803 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008804#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008805 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008806#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008807
8808 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008809
Victor Stinner65170952011-11-22 22:16:17 +01008810 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008811 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008812
Victor Stinner984890f2011-11-24 13:53:38 +01008813#ifdef HAVE_BROKEN_UNSETENV
8814 unsetenv(PyBytes_AS_STRING(name));
8815#else
Victor Stinner65170952011-11-22 22:16:17 +01008816 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008817 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008818 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008819 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008820 }
Victor Stinner984890f2011-11-24 13:53:38 +01008821#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008822
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 /* Remove the key from posix_putenv_garbage;
8824 * this will cause it to be collected. This has to
8825 * happen after the real unsetenv() call because the
8826 * old value was still accessible until then.
8827 */
Victor Stinner65170952011-11-22 22:16:17 +01008828 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 /* really not much we can do; just leak */
8830 PyErr_Clear();
8831 }
Victor Stinner65170952011-11-22 22:16:17 +01008832 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008833 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008834}
8835#endif /* unsetenv */
8836
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008837PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008838"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008839Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008840
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008842posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008843{
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 int code;
8845 char *message;
8846 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8847 return NULL;
8848 message = strerror(code);
8849 if (message == NULL) {
8850 PyErr_SetString(PyExc_ValueError,
8851 "strerror() argument out of range");
8852 return NULL;
8853 }
Victor Stinner1b579672011-12-17 05:47:23 +01008854 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008855}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008856
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008857
Guido van Rossumc9641791998-08-04 15:26:23 +00008858#ifdef HAVE_SYS_WAIT_H
8859
Fred Drake106c1a02002-04-23 15:58:02 +00008860#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008861PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008862"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008863Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008864
8865static PyObject *
8866posix_WCOREDUMP(PyObject *self, PyObject *args)
8867{
Victor Stinner8c62be82010-05-06 00:08:46 +00008868 WAIT_TYPE status;
8869 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008870
Victor Stinner8c62be82010-05-06 00:08:46 +00008871 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8872 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008873
Victor Stinner8c62be82010-05-06 00:08:46 +00008874 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008875}
8876#endif /* WCOREDUMP */
8877
8878#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008879PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008880"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008881Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008882job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008883
8884static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008885posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008886{
Victor Stinner8c62be82010-05-06 00:08:46 +00008887 WAIT_TYPE status;
8888 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008889
Victor Stinner8c62be82010-05-06 00:08:46 +00008890 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8891 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008892
Victor Stinner8c62be82010-05-06 00:08:46 +00008893 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008894}
8895#endif /* WIFCONTINUED */
8896
Guido van Rossumc9641791998-08-04 15:26:23 +00008897#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008898PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008899"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008900Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008901
8902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008903posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008904{
Victor Stinner8c62be82010-05-06 00:08:46 +00008905 WAIT_TYPE status;
8906 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008907
Victor Stinner8c62be82010-05-06 00:08:46 +00008908 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8909 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008910
Victor Stinner8c62be82010-05-06 00:08:46 +00008911 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008912}
8913#endif /* WIFSTOPPED */
8914
8915#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008916PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008917"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008918Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008919
8920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008921posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008922{
Victor Stinner8c62be82010-05-06 00:08:46 +00008923 WAIT_TYPE status;
8924 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008925
Victor Stinner8c62be82010-05-06 00:08:46 +00008926 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8927 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008928
Victor Stinner8c62be82010-05-06 00:08:46 +00008929 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008930}
8931#endif /* WIFSIGNALED */
8932
8933#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008934PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008935"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008936Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008937system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008938
8939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008940posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008941{
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 WAIT_TYPE status;
8943 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008944
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8946 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008947
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008949}
8950#endif /* WIFEXITED */
8951
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008952#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008953PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008954"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008955Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008956
8957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008958posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008959{
Victor Stinner8c62be82010-05-06 00:08:46 +00008960 WAIT_TYPE status;
8961 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008962
Victor Stinner8c62be82010-05-06 00:08:46 +00008963 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8964 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008965
Victor Stinner8c62be82010-05-06 00:08:46 +00008966 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008967}
8968#endif /* WEXITSTATUS */
8969
8970#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008971PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008972"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008973Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008974value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008975
8976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008977posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008978{
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 WAIT_TYPE status;
8980 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008981
Victor Stinner8c62be82010-05-06 00:08:46 +00008982 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8983 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008984
Victor Stinner8c62be82010-05-06 00:08:46 +00008985 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008986}
8987#endif /* WTERMSIG */
8988
8989#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008990PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008991"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008992Return the signal that stopped the process that provided\n\
8993the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008994
8995static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008996posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008997{
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 WAIT_TYPE status;
8999 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009000
Victor Stinner8c62be82010-05-06 00:08:46 +00009001 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9002 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009003
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009005}
9006#endif /* WSTOPSIG */
9007
9008#endif /* HAVE_SYS_WAIT_H */
9009
9010
Thomas Wouters477c8d52006-05-27 19:21:47 +00009011#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009012#ifdef _SCO_DS
9013/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9014 needed definitions in sys/statvfs.h */
9015#define _SVID3
9016#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009017#include <sys/statvfs.h>
9018
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009019static PyObject*
9020_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009021 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9022 if (v == NULL)
9023 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009024
9025#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009026 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9027 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9028 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9029 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9030 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9031 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9032 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9033 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9034 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9035 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009036#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009037 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9038 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9039 PyStructSequence_SET_ITEM(v, 2,
9040 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9041 PyStructSequence_SET_ITEM(v, 3,
9042 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9043 PyStructSequence_SET_ITEM(v, 4,
9044 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9045 PyStructSequence_SET_ITEM(v, 5,
9046 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9047 PyStructSequence_SET_ITEM(v, 6,
9048 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9049 PyStructSequence_SET_ITEM(v, 7,
9050 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9051 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9052 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009053#endif
9054
Victor Stinner8c62be82010-05-06 00:08:46 +00009055 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009056}
9057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009058PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009059"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009060Perform an fstatvfs system call on the given fd.\n\
9061Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009062
9063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009064posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009065{
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 int fd, res;
9067 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009068
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9070 return NULL;
9071 Py_BEGIN_ALLOW_THREADS
9072 res = fstatvfs(fd, &st);
9073 Py_END_ALLOW_THREADS
9074 if (res != 0)
9075 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009076
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009078}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009079#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009080
9081
Thomas Wouters477c8d52006-05-27 19:21:47 +00009082#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009083#include <sys/statvfs.h>
9084
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009085PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009086"statvfs(path)\n\n\
9087Perform a statvfs system call on the given path.\n\
9088\n\
9089path may always be specified as a string.\n\
9090On some platforms, path may also be specified as an open file descriptor.\n\
9091 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009092
9093static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009094posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009095{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009096 static char *keywords[] = {"path", NULL};
9097 path_t path;
9098 int result;
9099 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009100 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009101
Larry Hastings9cf065c2012-06-22 16:30:09 -07009102 memset(&path, 0, sizeof(path));
9103#ifdef HAVE_FSTATVFS
9104 path.allow_fd = 1;
9105#endif
9106 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9107 path_converter, &path
9108 ))
9109 return NULL;
9110
9111 Py_BEGIN_ALLOW_THREADS
9112#ifdef HAVE_FSTATVFS
9113 if (path.fd != -1) {
9114#ifdef __APPLE__
9115 /* handle weak-linking on Mac OS X 10.3 */
9116 if (fstatvfs == NULL) {
9117 fd_specified("statvfs", path.fd);
9118 goto exit;
9119 }
9120#endif
9121 result = fstatvfs(path.fd, &st);
9122 }
9123 else
9124#endif
9125 result = statvfs(path.narrow, &st);
9126 Py_END_ALLOW_THREADS
9127
9128 if (result) {
9129 return_value = path_posix_error("statvfs", &path);
9130 goto exit;
9131 }
9132
9133 return_value = _pystatvfs_fromstructstatvfs(st);
9134
9135exit:
9136 path_cleanup(&path);
9137 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009138}
9139#endif /* HAVE_STATVFS */
9140
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009141#ifdef MS_WINDOWS
9142PyDoc_STRVAR(win32__getdiskusage__doc__,
9143"_getdiskusage(path) -> (total, free)\n\n\
9144Return disk usage statistics about the given path as (total, free) tuple.");
9145
9146static PyObject *
9147win32__getdiskusage(PyObject *self, PyObject *args)
9148{
9149 BOOL retval;
9150 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009151 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009152
Victor Stinner6139c1b2011-11-09 22:14:14 +01009153 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009154 return NULL;
9155
9156 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009157 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009158 Py_END_ALLOW_THREADS
9159 if (retval == 0)
9160 return PyErr_SetFromWindowsErr(0);
9161
9162 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9163}
9164#endif
9165
9166
Fred Drakec9680921999-12-13 16:37:25 +00009167/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9168 * It maps strings representing configuration variable names to
9169 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009170 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009171 * rarely-used constants. There are three separate tables that use
9172 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009173 *
9174 * This code is always included, even if none of the interfaces that
9175 * need it are included. The #if hackery needed to avoid it would be
9176 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009177 */
9178struct constdef {
9179 char *name;
9180 long value;
9181};
9182
Fred Drake12c6e2d1999-12-14 21:25:03 +00009183static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009184conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009185 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009186{
Christian Heimes217cfd12007-12-02 14:31:20 +00009187 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009188 *valuep = PyLong_AS_LONG(arg);
9189 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009190 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009191 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009192 /* look up the value in the table using a binary search */
9193 size_t lo = 0;
9194 size_t mid;
9195 size_t hi = tablesize;
9196 int cmp;
9197 const char *confname;
9198 if (!PyUnicode_Check(arg)) {
9199 PyErr_SetString(PyExc_TypeError,
9200 "configuration names must be strings or integers");
9201 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009203 confname = _PyUnicode_AsString(arg);
9204 if (confname == NULL)
9205 return 0;
9206 while (lo < hi) {
9207 mid = (lo + hi) / 2;
9208 cmp = strcmp(confname, table[mid].name);
9209 if (cmp < 0)
9210 hi = mid;
9211 else if (cmp > 0)
9212 lo = mid + 1;
9213 else {
9214 *valuep = table[mid].value;
9215 return 1;
9216 }
9217 }
9218 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9219 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009220 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009221}
9222
9223
9224#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9225static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009226#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009227 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009228#endif
9229#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009230 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009231#endif
Fred Drakec9680921999-12-13 16:37:25 +00009232#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009233 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009234#endif
9235#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009236 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009237#endif
9238#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009239 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009240#endif
9241#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009242 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009243#endif
9244#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009246#endif
9247#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009248 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009249#endif
9250#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009252#endif
9253#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009254 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009255#endif
9256#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009258#endif
9259#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009260 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009261#endif
9262#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009263 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009264#endif
9265#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009266 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009267#endif
9268#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009269 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009270#endif
9271#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009272 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009273#endif
9274#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009275 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009276#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009277#ifdef _PC_ACL_ENABLED
9278 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9279#endif
9280#ifdef _PC_MIN_HOLE_SIZE
9281 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9282#endif
9283#ifdef _PC_ALLOC_SIZE_MIN
9284 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9285#endif
9286#ifdef _PC_REC_INCR_XFER_SIZE
9287 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9288#endif
9289#ifdef _PC_REC_MAX_XFER_SIZE
9290 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9291#endif
9292#ifdef _PC_REC_MIN_XFER_SIZE
9293 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9294#endif
9295#ifdef _PC_REC_XFER_ALIGN
9296 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9297#endif
9298#ifdef _PC_SYMLINK_MAX
9299 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9300#endif
9301#ifdef _PC_XATTR_ENABLED
9302 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9303#endif
9304#ifdef _PC_XATTR_EXISTS
9305 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9306#endif
9307#ifdef _PC_TIMESTAMP_RESOLUTION
9308 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9309#endif
Fred Drakec9680921999-12-13 16:37:25 +00009310};
9311
Fred Drakec9680921999-12-13 16:37:25 +00009312static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009313conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009314{
9315 return conv_confname(arg, valuep, posix_constants_pathconf,
9316 sizeof(posix_constants_pathconf)
9317 / sizeof(struct constdef));
9318}
9319#endif
9320
9321#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009322PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009323"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009324Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009325If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009326
9327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009328posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009329{
9330 PyObject *result = NULL;
9331 int name, fd;
9332
Fred Drake12c6e2d1999-12-14 21:25:03 +00009333 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9334 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009335 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009336
Stefan Krah0e803b32010-11-26 16:16:47 +00009337 errno = 0;
9338 limit = fpathconf(fd, name);
9339 if (limit == -1 && errno != 0)
9340 posix_error();
9341 else
9342 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009343 }
9344 return result;
9345}
9346#endif
9347
9348
9349#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009350PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009351"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009352Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009353If there is no limit, return -1.\n\
9354On some platforms, path may also be specified as an open file descriptor.\n\
9355 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009356
9357static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009358posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009359{
Georg Brandl306336b2012-06-24 12:55:33 +02009360 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009361 PyObject *result = NULL;
9362 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009363 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009364
Georg Brandl306336b2012-06-24 12:55:33 +02009365 memset(&path, 0, sizeof(path));
9366#ifdef HAVE_FPATHCONF
9367 path.allow_fd = 1;
9368#endif
9369 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9370 path_converter, &path,
9371 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009373
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009375#ifdef HAVE_FPATHCONF
9376 if (path.fd != -1)
9377 limit = fpathconf(path.fd, name);
9378 else
9379#endif
9380 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 if (limit == -1 && errno != 0) {
9382 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009383 /* could be a path or name problem */
9384 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009385 else
Georg Brandl306336b2012-06-24 12:55:33 +02009386 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 }
9388 else
9389 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009390 }
Georg Brandl306336b2012-06-24 12:55:33 +02009391 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009392 return result;
9393}
9394#endif
9395
9396#ifdef HAVE_CONFSTR
9397static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009398#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009400#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009401#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009403#endif
9404#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009406#endif
Fred Draked86ed291999-12-15 15:34:33 +00009407#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009409#endif
9410#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009411 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009412#endif
9413#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009414 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009415#endif
9416#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009417 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009418#endif
Fred Drakec9680921999-12-13 16:37:25 +00009419#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009420 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009421#endif
9422#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009423 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009424#endif
9425#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009426 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009427#endif
9428#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009429 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009430#endif
9431#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009432 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009433#endif
9434#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009436#endif
9437#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009438 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009439#endif
9440#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009442#endif
Fred Draked86ed291999-12-15 15:34:33 +00009443#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009444 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009445#endif
Fred Drakec9680921999-12-13 16:37:25 +00009446#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009448#endif
Fred Draked86ed291999-12-15 15:34:33 +00009449#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009451#endif
9452#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009453 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009454#endif
9455#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009457#endif
9458#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009459 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009460#endif
Fred Drakec9680921999-12-13 16:37:25 +00009461#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009463#endif
9464#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009466#endif
9467#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009468 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009469#endif
9470#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009471 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009472#endif
9473#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009474 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009475#endif
9476#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009477 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009478#endif
9479#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009480 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009481#endif
9482#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009483 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009484#endif
9485#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009486 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009487#endif
9488#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009489 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009490#endif
9491#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009492 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009493#endif
9494#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009495 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009496#endif
9497#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009499#endif
9500#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009502#endif
9503#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009505#endif
9506#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009508#endif
Fred Draked86ed291999-12-15 15:34:33 +00009509#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009511#endif
9512#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009514#endif
9515#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009517#endif
9518#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009520#endif
9521#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009523#endif
9524#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009526#endif
9527#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009529#endif
9530#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009532#endif
9533#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009535#endif
9536#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009538#endif
9539#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009541#endif
9542#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009544#endif
9545#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009547#endif
Fred Drakec9680921999-12-13 16:37:25 +00009548};
9549
9550static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009551conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009552{
9553 return conv_confname(arg, valuep, posix_constants_confstr,
9554 sizeof(posix_constants_confstr)
9555 / sizeof(struct constdef));
9556}
9557
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009558PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009559"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009560Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009561
9562static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009563posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009564{
9565 PyObject *result = NULL;
9566 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009567 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009568 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009569
Victor Stinnercb043522010-09-10 23:49:04 +00009570 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9571 return NULL;
9572
9573 errno = 0;
9574 len = confstr(name, buffer, sizeof(buffer));
9575 if (len == 0) {
9576 if (errno) {
9577 posix_error();
9578 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009579 }
9580 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009581 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009582 }
9583 }
Victor Stinnercb043522010-09-10 23:49:04 +00009584
9585 if ((unsigned int)len >= sizeof(buffer)) {
9586 char *buf = PyMem_Malloc(len);
9587 if (buf == NULL)
9588 return PyErr_NoMemory();
9589 confstr(name, buf, len);
9590 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9591 PyMem_Free(buf);
9592 }
9593 else
9594 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009595 return result;
9596}
9597#endif
9598
9599
9600#ifdef HAVE_SYSCONF
9601static struct constdef posix_constants_sysconf[] = {
9602#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009604#endif
9605#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009607#endif
9608#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009610#endif
9611#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009613#endif
9614#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009616#endif
9617#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009619#endif
9620#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009622#endif
9623#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
9626#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009628#endif
9629#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
Fred Draked86ed291999-12-15 15:34:33 +00009632#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009634#endif
9635#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009637#endif
Fred Drakec9680921999-12-13 16:37:25 +00009638#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009640#endif
Fred Drakec9680921999-12-13 16:37:25 +00009641#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009643#endif
9644#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009646#endif
9647#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009649#endif
9650#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009652#endif
9653#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009655#endif
Fred Draked86ed291999-12-15 15:34:33 +00009656#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009658#endif
Fred Drakec9680921999-12-13 16:37:25 +00009659#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009661#endif
9662#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009664#endif
9665#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009667#endif
9668#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009670#endif
9671#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009673#endif
Fred Draked86ed291999-12-15 15:34:33 +00009674#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009676#endif
Fred Drakec9680921999-12-13 16:37:25 +00009677#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009679#endif
9680#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009682#endif
9683#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009685#endif
9686#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009688#endif
9689#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009691#endif
9692#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
9695#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
9698#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
9713#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009715#endif
9716#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009718#endif
9719#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
9722#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009724#endif
9725#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
Fred Draked86ed291999-12-15 15:34:33 +00009746#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009748#endif
Fred Drakec9680921999-12-13 16:37:25 +00009749#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
Fred Draked86ed291999-12-15 15:34:33 +00009758#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
Fred Drakec9680921999-12-13 16:37:25 +00009761#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
Fred Draked86ed291999-12-15 15:34:33 +00009764#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009766#endif
9767#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009769#endif
Fred Drakec9680921999-12-13 16:37:25 +00009770#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
Fred Draked86ed291999-12-15 15:34:33 +00009782#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009784#endif
Fred Drakec9680921999-12-13 16:37:25 +00009785#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
Fred Draked86ed291999-12-15 15:34:33 +00009806#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009808#endif
Fred Drakec9680921999-12-13 16:37:25 +00009809#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
Fred Draked86ed291999-12-15 15:34:33 +00009815#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009817#endif
Fred Drakec9680921999-12-13 16:37:25 +00009818#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
Fred Draked86ed291999-12-15 15:34:33 +00009845#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009847#endif
9848#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009850#endif
Fred Drakec9680921999-12-13 16:37:25 +00009851#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
9890#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
Fred Draked86ed291999-12-15 15:34:33 +00009956#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009958#endif
Fred Drakec9680921999-12-13 16:37:25 +00009959#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094};
10095
10096static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010097conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010098{
10099 return conv_confname(arg, valuep, posix_constants_sysconf,
10100 sizeof(posix_constants_sysconf)
10101 / sizeof(struct constdef));
10102}
10103
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010104PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010105"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010106Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010107
10108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010109posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010110{
10111 PyObject *result = NULL;
10112 int name;
10113
10114 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10115 int value;
10116
10117 errno = 0;
10118 value = sysconf(name);
10119 if (value == -1 && errno != 0)
10120 posix_error();
10121 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010122 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010123 }
10124 return result;
10125}
10126#endif
10127
10128
Fred Drakebec628d1999-12-15 18:31:10 +000010129/* This code is used to ensure that the tables of configuration value names
10130 * are in sorted order as required by conv_confname(), and also to build the
10131 * the exported dictionaries that are used to publish information about the
10132 * names available on the host platform.
10133 *
10134 * Sorting the table at runtime ensures that the table is properly ordered
10135 * when used, even for platforms we're not able to test on. It also makes
10136 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010137 */
Fred Drakebec628d1999-12-15 18:31:10 +000010138
10139static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010140cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010141{
10142 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010144 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010146
10147 return strcmp(c1->name, c2->name);
10148}
10149
10150static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010151setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010153{
Fred Drakebec628d1999-12-15 18:31:10 +000010154 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010155 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010156
10157 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10158 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010159 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010161
Barry Warsaw3155db32000-04-13 15:20:40 +000010162 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 PyObject *o = PyLong_FromLong(table[i].value);
10164 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10165 Py_XDECREF(o);
10166 Py_DECREF(d);
10167 return -1;
10168 }
10169 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010170 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010171 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010172}
10173
Fred Drakebec628d1999-12-15 18:31:10 +000010174/* Return -1 on failure, 0 on success. */
10175static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010176setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010177{
10178#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010179 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010180 sizeof(posix_constants_pathconf)
10181 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010182 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010183 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010184#endif
10185#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010186 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010187 sizeof(posix_constants_confstr)
10188 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010189 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010190 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010191#endif
10192#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010193 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010194 sizeof(posix_constants_sysconf)
10195 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010196 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010197 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010198#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010199 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010200}
Fred Draked86ed291999-12-15 15:34:33 +000010201
10202
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010203PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010204"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010205Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010206in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010207
10208static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010209posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010210{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010211 abort();
10212 /*NOTREACHED*/
10213 Py_FatalError("abort() called from Python code didn't abort!");
10214 return NULL;
10215}
Fred Drakebec628d1999-12-15 18:31:10 +000010216
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010217#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010218PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010219"startfile(filepath [, operation]) - Start a file with its associated\n\
10220application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010221\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010222When \"operation\" is not specified or \"open\", this acts like\n\
10223double-clicking the file in Explorer, or giving the file name as an\n\
10224argument to the DOS \"start\" command: the file is opened with whatever\n\
10225application (if any) its extension is associated.\n\
10226When another \"operation\" is given, it specifies what should be done with\n\
10227the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010228\n\
10229startfile returns as soon as the associated application is launched.\n\
10230There is no option to wait for the application to close, and no way\n\
10231to retrieve the application's exit status.\n\
10232\n\
10233The filepath is relative to the current directory. If you want to use\n\
10234an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010235the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010236
10237static PyObject *
10238win32_startfile(PyObject *self, PyObject *args)
10239{
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 PyObject *ofilepath;
10241 char *filepath;
10242 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010243 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010245
Victor Stinnereb5657a2011-09-30 01:44:27 +020010246 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 if (!PyArg_ParseTuple(args, "U|s:startfile",
10248 &unipath, &operation)) {
10249 PyErr_Clear();
10250 goto normal;
10251 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010252
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010254 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010256 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 PyErr_Clear();
10258 operation = NULL;
10259 goto normal;
10260 }
10261 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010262
Victor Stinnereb5657a2011-09-30 01:44:27 +020010263 wpath = PyUnicode_AsUnicode(unipath);
10264 if (wpath == NULL)
10265 goto normal;
10266 if (uoperation) {
10267 woperation = PyUnicode_AsUnicode(uoperation);
10268 if (woperation == NULL)
10269 goto normal;
10270 }
10271 else
10272 woperation = NULL;
10273
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010275 rc = ShellExecuteW((HWND)0, woperation, wpath,
10276 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 Py_END_ALLOW_THREADS
10278
Victor Stinnereb5657a2011-09-30 01:44:27 +020010279 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010281 win32_error_object("startfile", unipath);
10282 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 }
10284 Py_INCREF(Py_None);
10285 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010286
10287normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10289 PyUnicode_FSConverter, &ofilepath,
10290 &operation))
10291 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010292 if (win32_warn_bytes_api()) {
10293 Py_DECREF(ofilepath);
10294 return NULL;
10295 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 filepath = PyBytes_AsString(ofilepath);
10297 Py_BEGIN_ALLOW_THREADS
10298 rc = ShellExecute((HWND)0, operation, filepath,
10299 NULL, NULL, SW_SHOWNORMAL);
10300 Py_END_ALLOW_THREADS
10301 if (rc <= (HINSTANCE)32) {
10302 PyObject *errval = win32_error("startfile", filepath);
10303 Py_DECREF(ofilepath);
10304 return errval;
10305 }
10306 Py_DECREF(ofilepath);
10307 Py_INCREF(Py_None);
10308 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010309}
10310#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010311
Martin v. Löwis438b5342002-12-27 10:16:42 +000010312#ifdef HAVE_GETLOADAVG
10313PyDoc_STRVAR(posix_getloadavg__doc__,
10314"getloadavg() -> (float, float, float)\n\n\
10315Return the number of processes in the system run queue averaged over\n\
10316the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10317was unobtainable");
10318
10319static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010320posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010321{
10322 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010323 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010324 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10325 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010326 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010327 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010328}
10329#endif
10330
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010331PyDoc_STRVAR(device_encoding__doc__,
10332"device_encoding(fd) -> str\n\n\
10333Return a string describing the encoding of the device\n\
10334if the output is a terminal; else return None.");
10335
10336static PyObject *
10337device_encoding(PyObject *self, PyObject *args)
10338{
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010340
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10342 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010343
10344 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010345}
10346
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010347#ifdef HAVE_SETRESUID
10348PyDoc_STRVAR(posix_setresuid__doc__,
10349"setresuid(ruid, euid, suid)\n\n\
10350Set the current process's real, effective, and saved user ids.");
10351
10352static PyObject*
10353posix_setresuid (PyObject *self, PyObject *args)
10354{
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 /* We assume uid_t is no larger than a long. */
10356 long ruid, euid, suid;
10357 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
10358 return NULL;
10359 if (setresuid(ruid, euid, suid) < 0)
10360 return posix_error();
10361 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010362}
10363#endif
10364
10365#ifdef HAVE_SETRESGID
10366PyDoc_STRVAR(posix_setresgid__doc__,
10367"setresgid(rgid, egid, sgid)\n\n\
10368Set the current process's real, effective, and saved group ids.");
10369
10370static PyObject*
10371posix_setresgid (PyObject *self, PyObject *args)
10372{
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 /* We assume uid_t is no larger than a long. */
10374 long rgid, egid, sgid;
10375 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
10376 return NULL;
10377 if (setresgid(rgid, egid, sgid) < 0)
10378 return posix_error();
10379 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010380}
10381#endif
10382
10383#ifdef HAVE_GETRESUID
10384PyDoc_STRVAR(posix_getresuid__doc__,
10385"getresuid() -> (ruid, euid, suid)\n\n\
10386Get tuple of the current process's real, effective, and saved user ids.");
10387
10388static PyObject*
10389posix_getresuid (PyObject *self, PyObject *noargs)
10390{
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 uid_t ruid, euid, suid;
10392 long l_ruid, l_euid, l_suid;
10393 if (getresuid(&ruid, &euid, &suid) < 0)
10394 return posix_error();
10395 /* Force the values into long's as we don't know the size of uid_t. */
10396 l_ruid = ruid;
10397 l_euid = euid;
10398 l_suid = suid;
10399 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010400}
10401#endif
10402
10403#ifdef HAVE_GETRESGID
10404PyDoc_STRVAR(posix_getresgid__doc__,
10405"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010406Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010407
10408static PyObject*
10409posix_getresgid (PyObject *self, PyObject *noargs)
10410{
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 uid_t rgid, egid, sgid;
10412 long l_rgid, l_egid, l_sgid;
10413 if (getresgid(&rgid, &egid, &sgid) < 0)
10414 return posix_error();
10415 /* Force the values into long's as we don't know the size of uid_t. */
10416 l_rgid = rgid;
10417 l_egid = egid;
10418 l_sgid = sgid;
10419 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010420}
10421#endif
10422
Benjamin Peterson9428d532011-09-14 11:45:52 -040010423#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010424
Benjamin Peterson799bd802011-08-31 22:15:17 -040010425PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010426"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10427Return the value of extended attribute attribute on path.\n\
10428\n\
10429path may be either a string or an open file descriptor.\n\
10430If follow_symlinks is False, and the last element of the path is a symbolic\n\
10431 link, getxattr will examine the symbolic link itself instead of the file\n\
10432 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010433
10434static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010435posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010436{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010437 path_t path;
10438 path_t attribute;
10439 int follow_symlinks = 1;
10440 PyObject *buffer = NULL;
10441 int i;
10442 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010443
Larry Hastings9cf065c2012-06-22 16:30:09 -070010444 memset(&path, 0, sizeof(path));
10445 memset(&attribute, 0, sizeof(attribute));
10446 path.allow_fd = 1;
10447 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10448 path_converter, &path,
10449 path_converter, &attribute,
10450 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010451 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010452
Larry Hastings9cf065c2012-06-22 16:30:09 -070010453 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10454 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010455
Larry Hastings9cf065c2012-06-22 16:30:09 -070010456 for (i = 0; ; i++) {
10457 void *ptr;
10458 ssize_t result;
10459 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10460 Py_ssize_t buffer_size = buffer_sizes[i];
10461 if (!buffer_size) {
10462 path_error("getxattr", &path);
10463 goto exit;
10464 }
10465 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10466 if (!buffer)
10467 goto exit;
10468 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010469
Larry Hastings9cf065c2012-06-22 16:30:09 -070010470 Py_BEGIN_ALLOW_THREADS;
10471 if (path.fd >= 0)
10472 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10473 else if (follow_symlinks)
10474 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10475 else
10476 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10477 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010478
Larry Hastings9cf065c2012-06-22 16:30:09 -070010479 if (result < 0) {
10480 Py_DECREF(buffer);
10481 buffer = NULL;
10482 if (errno == ERANGE)
10483 continue;
10484 path_error("getxattr", &path);
10485 goto exit;
10486 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010487
Larry Hastings9cf065c2012-06-22 16:30:09 -070010488 if (result != buffer_size) {
10489 /* Can only shrink. */
10490 _PyBytes_Resize(&buffer, result);
10491 }
10492 break;
10493 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010494
Larry Hastings9cf065c2012-06-22 16:30:09 -070010495exit:
10496 path_cleanup(&path);
10497 path_cleanup(&attribute);
10498 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010499}
10500
10501PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010502"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10503Set extended attribute attribute on path to value.\n\
10504path may be either a string or an open file descriptor.\n\
10505If follow_symlinks is False, and the last element of the path is a symbolic\n\
10506 link, setxattr will modify the symbolic link itself instead of the file\n\
10507 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010508
10509static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010510posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010511{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010512 path_t path;
10513 path_t attribute;
10514 Py_buffer value;
10515 int flags = 0;
10516 int follow_symlinks = 1;
10517 int result;
10518 PyObject *return_value = NULL;
10519 static char *keywords[] = {"path", "attribute", "value",
10520 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010521
Larry Hastings9cf065c2012-06-22 16:30:09 -070010522 memset(&path, 0, sizeof(path));
10523 path.allow_fd = 1;
10524 memset(&attribute, 0, sizeof(attribute));
10525 memset(&value, 0, sizeof(value));
10526 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10527 keywords,
10528 path_converter, &path,
10529 path_converter, &attribute,
10530 &value, &flags,
10531 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010532 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010533
10534 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10535 goto exit;
10536
Benjamin Peterson799bd802011-08-31 22:15:17 -040010537 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010538 if (path.fd > -1)
10539 result = fsetxattr(path.fd, attribute.narrow,
10540 value.buf, value.len, flags);
10541 else if (follow_symlinks)
10542 result = setxattr(path.narrow, attribute.narrow,
10543 value.buf, value.len, flags);
10544 else
10545 result = lsetxattr(path.narrow, attribute.narrow,
10546 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010547 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010548
Larry Hastings9cf065c2012-06-22 16:30:09 -070010549 if (result) {
10550 return_value = path_error("setxattr", &path);
10551 goto exit;
10552 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010553
Larry Hastings9cf065c2012-06-22 16:30:09 -070010554 return_value = Py_None;
10555 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010556
Larry Hastings9cf065c2012-06-22 16:30:09 -070010557exit:
10558 path_cleanup(&path);
10559 path_cleanup(&attribute);
10560 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010561
Larry Hastings9cf065c2012-06-22 16:30:09 -070010562 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010563}
10564
10565PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010566"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10567Remove extended attribute attribute on path.\n\
10568path may be either a string or an open file descriptor.\n\
10569If follow_symlinks is False, and the last element of the path is a symbolic\n\
10570 link, removexattr will modify the symbolic link itself instead of the file\n\
10571 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010572
10573static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010574posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010575{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010576 path_t path;
10577 path_t attribute;
10578 int follow_symlinks = 1;
10579 int result;
10580 PyObject *return_value = NULL;
10581 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010582
Larry Hastings9cf065c2012-06-22 16:30:09 -070010583 memset(&path, 0, sizeof(path));
10584 memset(&attribute, 0, sizeof(attribute));
10585 path.allow_fd = 1;
10586 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10587 keywords,
10588 path_converter, &path,
10589 path_converter, &attribute,
10590 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010591 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010592
10593 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10594 goto exit;
10595
Benjamin Peterson799bd802011-08-31 22:15:17 -040010596 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010597 if (path.fd > -1)
10598 result = fremovexattr(path.fd, attribute.narrow);
10599 else if (follow_symlinks)
10600 result = removexattr(path.narrow, attribute.narrow);
10601 else
10602 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010603 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010604
Larry Hastings9cf065c2012-06-22 16:30:09 -070010605 if (result) {
10606 return_value = path_error("removexattr", &path);
10607 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010608 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010609
Larry Hastings9cf065c2012-06-22 16:30:09 -070010610 return_value = Py_None;
10611 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010612
Larry Hastings9cf065c2012-06-22 16:30:09 -070010613exit:
10614 path_cleanup(&path);
10615 path_cleanup(&attribute);
10616
10617 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010618}
10619
10620PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621"listxattr(path='.', *, follow_symlinks=True)\n\n\
10622Return a list of extended attributes on path.\n\
10623\n\
10624path may be either None, a string, or an open file descriptor.\n\
10625if path is None, listxattr will examine the current directory.\n\
10626If follow_symlinks is False, and the last element of the path is a symbolic\n\
10627 link, listxattr will examine the symbolic link itself instead of the file\n\
10628 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010629
10630static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010631posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010632{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010633 path_t path;
10634 int follow_symlinks = 1;
10635 Py_ssize_t i;
10636 PyObject *result = NULL;
10637 char *buffer = NULL;
10638 char *name;
10639 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010640
Larry Hastings9cf065c2012-06-22 16:30:09 -070010641 memset(&path, 0, sizeof(path));
10642 path.allow_fd = 1;
10643 path.fd = -1;
10644 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10645 path_converter, &path,
10646 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010647 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010648
Larry Hastings9cf065c2012-06-22 16:30:09 -070010649 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10650 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010651
Larry Hastings9cf065c2012-06-22 16:30:09 -070010652 name = path.narrow ? path.narrow : ".";
10653 for (i = 0; ; i++) {
10654 char *start, *trace, *end;
10655 ssize_t length;
10656 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10657 Py_ssize_t buffer_size = buffer_sizes[i];
10658 if (!buffer_size) {
10659 // ERANGE
10660 path_error("listxattr", &path);
10661 break;
10662 }
10663 buffer = PyMem_MALLOC(buffer_size);
10664 if (!buffer) {
10665 PyErr_NoMemory();
10666 break;
10667 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010668
Larry Hastings9cf065c2012-06-22 16:30:09 -070010669 Py_BEGIN_ALLOW_THREADS;
10670 if (path.fd > -1)
10671 length = flistxattr(path.fd, buffer, buffer_size);
10672 else if (follow_symlinks)
10673 length = listxattr(name, buffer, buffer_size);
10674 else
10675 length = llistxattr(name, buffer, buffer_size);
10676 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010677
Larry Hastings9cf065c2012-06-22 16:30:09 -070010678 if (length < 0) {
10679 if (errno == ERANGE)
10680 continue;
10681 path_error("listxattr", &path);
10682 break;
10683 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010684
Larry Hastings9cf065c2012-06-22 16:30:09 -070010685 result = PyList_New(0);
10686 if (!result) {
10687 goto exit;
10688 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010689
Larry Hastings9cf065c2012-06-22 16:30:09 -070010690 end = buffer + length;
10691 for (trace = start = buffer; trace != end; trace++) {
10692 if (!*trace) {
10693 int error;
10694 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10695 trace - start);
10696 if (!attribute) {
10697 Py_DECREF(result);
10698 result = NULL;
10699 goto exit;
10700 }
10701 error = PyList_Append(result, attribute);
10702 Py_DECREF(attribute);
10703 if (error) {
10704 Py_DECREF(result);
10705 result = NULL;
10706 goto exit;
10707 }
10708 start = trace + 1;
10709 }
10710 }
10711 break;
10712 }
10713exit:
10714 path_cleanup(&path);
10715 if (buffer)
10716 PyMem_FREE(buffer);
10717 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010718}
10719
Benjamin Peterson9428d532011-09-14 11:45:52 -040010720#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010721
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010722
Georg Brandl2fb477c2012-02-21 00:33:36 +010010723PyDoc_STRVAR(posix_urandom__doc__,
10724"urandom(n) -> str\n\n\
10725Return n random bytes suitable for cryptographic use.");
10726
10727static PyObject *
10728posix_urandom(PyObject *self, PyObject *args)
10729{
10730 Py_ssize_t size;
10731 PyObject *result;
10732 int ret;
10733
10734 /* Read arguments */
10735 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10736 return NULL;
10737 if (size < 0)
10738 return PyErr_Format(PyExc_ValueError,
10739 "negative argument not allowed");
10740 result = PyBytes_FromStringAndSize(NULL, size);
10741 if (result == NULL)
10742 return NULL;
10743
10744 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10745 PyBytes_GET_SIZE(result));
10746 if (ret == -1) {
10747 Py_DECREF(result);
10748 return NULL;
10749 }
10750 return result;
10751}
10752
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010753/* Terminal size querying */
10754
10755static PyTypeObject TerminalSizeType;
10756
10757PyDoc_STRVAR(TerminalSize_docstring,
10758 "A tuple of (columns, lines) for holding terminal window size");
10759
10760static PyStructSequence_Field TerminalSize_fields[] = {
10761 {"columns", "width of the terminal window in characters"},
10762 {"lines", "height of the terminal window in characters"},
10763 {NULL, NULL}
10764};
10765
10766static PyStructSequence_Desc TerminalSize_desc = {
10767 "os.terminal_size",
10768 TerminalSize_docstring,
10769 TerminalSize_fields,
10770 2,
10771};
10772
10773#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10774PyDoc_STRVAR(termsize__doc__,
10775 "Return the size of the terminal window as (columns, lines).\n" \
10776 "\n" \
10777 "The optional argument fd (default standard output) specifies\n" \
10778 "which file descriptor should be queried.\n" \
10779 "\n" \
10780 "If the file descriptor is not connected to a terminal, an OSError\n" \
10781 "is thrown.\n" \
10782 "\n" \
10783 "This function will only be defined if an implementation is\n" \
10784 "available for this system.\n" \
10785 "\n" \
10786 "shutil.get_terminal_size is the high-level function which should \n" \
10787 "normally be used, os.get_terminal_size is the low-level implementation.");
10788
10789static PyObject*
10790get_terminal_size(PyObject *self, PyObject *args)
10791{
10792 int columns, lines;
10793 PyObject *termsize;
10794
10795 int fd = fileno(stdout);
10796 /* Under some conditions stdout may not be connected and
10797 * fileno(stdout) may point to an invalid file descriptor. For example
10798 * GUI apps don't have valid standard streams by default.
10799 *
10800 * If this happens, and the optional fd argument is not present,
10801 * the ioctl below will fail returning EBADF. This is what we want.
10802 */
10803
10804 if (!PyArg_ParseTuple(args, "|i", &fd))
10805 return NULL;
10806
10807#ifdef TERMSIZE_USE_IOCTL
10808 {
10809 struct winsize w;
10810 if (ioctl(fd, TIOCGWINSZ, &w))
10811 return PyErr_SetFromErrno(PyExc_OSError);
10812 columns = w.ws_col;
10813 lines = w.ws_row;
10814 }
10815#endif /* TERMSIZE_USE_IOCTL */
10816
10817#ifdef TERMSIZE_USE_CONIO
10818 {
10819 DWORD nhandle;
10820 HANDLE handle;
10821 CONSOLE_SCREEN_BUFFER_INFO csbi;
10822 switch (fd) {
10823 case 0: nhandle = STD_INPUT_HANDLE;
10824 break;
10825 case 1: nhandle = STD_OUTPUT_HANDLE;
10826 break;
10827 case 2: nhandle = STD_ERROR_HANDLE;
10828 break;
10829 default:
10830 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10831 }
10832 handle = GetStdHandle(nhandle);
10833 if (handle == NULL)
10834 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10835 if (handle == INVALID_HANDLE_VALUE)
10836 return PyErr_SetFromWindowsErr(0);
10837
10838 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10839 return PyErr_SetFromWindowsErr(0);
10840
10841 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10842 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10843 }
10844#endif /* TERMSIZE_USE_CONIO */
10845
10846 termsize = PyStructSequence_New(&TerminalSizeType);
10847 if (termsize == NULL)
10848 return NULL;
10849 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10850 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10851 if (PyErr_Occurred()) {
10852 Py_DECREF(termsize);
10853 return NULL;
10854 }
10855 return termsize;
10856}
10857#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10858
10859
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010860static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010861 {"access", (PyCFunction)posix_access,
10862 METH_VARARGS | METH_KEYWORDS,
10863 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010864#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010866#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010867 {"chdir", (PyCFunction)posix_chdir,
10868 METH_VARARGS | METH_KEYWORDS,
10869 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010870#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010871 {"chflags", (PyCFunction)posix_chflags,
10872 METH_VARARGS | METH_KEYWORDS,
10873 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010874#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010875 {"chmod", (PyCFunction)posix_chmod,
10876 METH_VARARGS | METH_KEYWORDS,
10877 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010878#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010880#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010881#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010882 {"chown", (PyCFunction)posix_chown,
10883 METH_VARARGS | METH_KEYWORDS,
10884 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010885#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010886#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010887 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010888#endif /* HAVE_LCHMOD */
10889#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010890 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010891#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010892#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010894#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010895#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010896 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010897#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010898#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010899 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010900#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010901#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010902 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010903#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010904#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10906 METH_NOARGS, posix_getcwd__doc__},
10907 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10908 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010909#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010910#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10911 {"link", (PyCFunction)posix_link,
10912 METH_VARARGS | METH_KEYWORDS,
10913 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010914#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010915 {"listdir", (PyCFunction)posix_listdir,
10916 METH_VARARGS | METH_KEYWORDS,
10917 posix_listdir__doc__},
10918 {"lstat", (PyCFunction)posix_lstat,
10919 METH_VARARGS | METH_KEYWORDS,
10920 posix_lstat__doc__},
10921 {"mkdir", (PyCFunction)posix_mkdir,
10922 METH_VARARGS | METH_KEYWORDS,
10923 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010924#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010925 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010926#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010927#ifdef HAVE_GETPRIORITY
10928 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10929#endif /* HAVE_GETPRIORITY */
10930#ifdef HAVE_SETPRIORITY
10931 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10932#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010933#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010934 {"readlink", (PyCFunction)posix_readlink,
10935 METH_VARARGS | METH_KEYWORDS,
10936 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010937#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010938#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010939 {"readlink", (PyCFunction)win_readlink,
10940 METH_VARARGS | METH_KEYWORDS,
10941 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010942#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010943 {"rename", (PyCFunction)posix_rename,
10944 METH_VARARGS | METH_KEYWORDS,
10945 posix_rename__doc__},
10946 {"replace", (PyCFunction)posix_replace,
10947 METH_VARARGS | METH_KEYWORDS,
10948 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010949 {"rmdir", (PyCFunction)posix_rmdir,
10950 METH_VARARGS | METH_KEYWORDS,
10951 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010952 {"stat", (PyCFunction)posix_stat,
10953 METH_VARARGS | METH_KEYWORDS,
10954 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010955 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010956#if defined(HAVE_SYMLINK)
10957 {"symlink", (PyCFunction)posix_symlink,
10958 METH_VARARGS | METH_KEYWORDS,
10959 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010960#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010961#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010962 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010963#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010965#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010967#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010968 {"unlink", (PyCFunction)posix_unlink,
10969 METH_VARARGS | METH_KEYWORDS,
10970 posix_unlink__doc__},
10971 {"remove", (PyCFunction)posix_unlink,
10972 METH_VARARGS | METH_KEYWORDS,
10973 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010974 {"utime", (PyCFunction)posix_utime,
10975 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010976#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010977 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010978#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010980#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010981 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010982 {"execve", (PyCFunction)posix_execve,
10983 METH_VARARGS | METH_KEYWORDS,
10984 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010985#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010986#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10988 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010989#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10991 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010992#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010993#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010994#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010996#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010997#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010999#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011000#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011001#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011002 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11003 {"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 +020011004#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011005#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011006 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011007#endif
11008#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011009 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011010#endif
11011#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011012 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011013#endif
11014#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011015 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011016#endif
11017#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011018 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011019#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011020 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011021#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011022 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11023 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11024#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011025#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011026#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011027 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011028#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011029#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011030 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011031#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011032#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011033 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011034#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011035#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011036 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011037#endif /* HAVE_GETEUID */
11038#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011039 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011040#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011041#ifdef HAVE_GETGROUPLIST
11042 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11043#endif
Fred Drakec9680921999-12-13 16:37:25 +000011044#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011045 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011046#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011048#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011050#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011051#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011053#endif /* HAVE_GETPPID */
11054#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011056#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011057#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011058 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011059#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011060#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011062#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011063#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011065#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011066#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011068#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011069#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11071 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011072#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011073#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011075#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011076#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011078#endif /* HAVE_SETEUID */
11079#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011081#endif /* HAVE_SETEGID */
11082#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011084#endif /* HAVE_SETREUID */
11085#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011087#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011088#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011090#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011091#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011092 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011093#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011094#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011096#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011097#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011098 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011099#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011100#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011102#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011103#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011105#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011106#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011107 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011108#endif /* HAVE_WAIT3 */
11109#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011110 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011111#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011112#if defined(HAVE_WAITID) && !defined(__APPLE__)
11113 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11114#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011115#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011117#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011118#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011120#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011121#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011123#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011124#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011126#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011127#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011129#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011130#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011132#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011133 {"open", (PyCFunction)posix_open,\
11134 METH_VARARGS | METH_KEYWORDS,
11135 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11137 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11138 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11139 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
11140 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011141#ifdef HAVE_LOCKF
11142 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11143#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11145 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011146#ifdef HAVE_READV
11147 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11148#endif
11149#ifdef HAVE_PREAD
11150 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11151#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011153#ifdef HAVE_WRITEV
11154 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11155#endif
11156#ifdef HAVE_PWRITE
11157 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11158#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011159#ifdef HAVE_SENDFILE
11160 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11161 posix_sendfile__doc__},
11162#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011163 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011165#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011167#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011168#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011169 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011170#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011171#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011172 {"mkfifo", (PyCFunction)posix_mkfifo,
11173 METH_VARARGS | METH_KEYWORDS,
11174 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011175#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011176#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011177 {"mknod", (PyCFunction)posix_mknod,
11178 METH_VARARGS | METH_KEYWORDS,
11179 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011180#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011181#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011182 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11183 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11184 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011185#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011186#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011188#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011189#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011190 {"truncate", (PyCFunction)posix_truncate,
11191 METH_VARARGS | METH_KEYWORDS,
11192 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011193#endif
11194#ifdef HAVE_POSIX_FALLOCATE
11195 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11196#endif
11197#ifdef HAVE_POSIX_FADVISE
11198 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11199#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011200#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011201 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011202#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011203#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011204 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011205#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011206 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011207#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011209#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011210#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011212#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011213#ifdef HAVE_SYNC
11214 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11215#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011216#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011218#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011219#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011220#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011221 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011222#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011223#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011225#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011226#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011227 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011228#endif /* WIFSTOPPED */
11229#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011231#endif /* WIFSIGNALED */
11232#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011234#endif /* WIFEXITED */
11235#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011236 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011237#endif /* WEXITSTATUS */
11238#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011240#endif /* WTERMSIG */
11241#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011243#endif /* WSTOPSIG */
11244#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011245#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011246 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011247#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011248#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011249 {"statvfs", (PyCFunction)posix_statvfs,
11250 METH_VARARGS | METH_KEYWORDS,
11251 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011252#endif
Fred Drakec9680921999-12-13 16:37:25 +000011253#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011255#endif
11256#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011258#endif
11259#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011260 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011261#endif
11262#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011263 {"pathconf", (PyCFunction)posix_pathconf,
11264 METH_VARARGS | METH_KEYWORDS,
11265 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011266#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011267 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011268#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011270 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011271 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011272 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011273 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011274#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011275#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011276 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011277#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011278 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011279#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011281#endif
11282#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011284#endif
11285#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011287#endif
11288#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011290#endif
11291
Benjamin Peterson9428d532011-09-14 11:45:52 -040011292#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011293 {"setxattr", (PyCFunction)posix_setxattr,
11294 METH_VARARGS | METH_KEYWORDS,
11295 posix_setxattr__doc__},
11296 {"getxattr", (PyCFunction)posix_getxattr,
11297 METH_VARARGS | METH_KEYWORDS,
11298 posix_getxattr__doc__},
11299 {"removexattr", (PyCFunction)posix_removexattr,
11300 METH_VARARGS | METH_KEYWORDS,
11301 posix_removexattr__doc__},
11302 {"listxattr", (PyCFunction)posix_listxattr,
11303 METH_VARARGS | METH_KEYWORDS,
11304 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011305#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011306#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11307 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11308#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011310};
11311
11312
Barry Warsaw4a342091996-12-19 23:50:02 +000011313static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011314ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011315{
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011317}
11318
Guido van Rossumd48f2521997-12-05 22:19:34 +000011319#if defined(PYOS_OS2)
11320/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011321static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011322{
11323 APIRET rc;
11324 ULONG values[QSV_MAX+1];
11325 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011326 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011327
11328 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011329 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011330 Py_END_ALLOW_THREADS
11331
11332 if (rc != NO_ERROR) {
11333 os2_error(rc);
11334 return -1;
11335 }
11336
Fred Drake4d1e64b2002-04-15 19:40:07 +000011337 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11338 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11339 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11340 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11341 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11342 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11343 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011344
11345 switch (values[QSV_VERSION_MINOR]) {
11346 case 0: ver = "2.00"; break;
11347 case 10: ver = "2.10"; break;
11348 case 11: ver = "2.11"; break;
11349 case 30: ver = "3.00"; break;
11350 case 40: ver = "4.00"; break;
11351 case 50: ver = "5.00"; break;
11352 default:
Tim Peters885d4572001-11-28 20:27:42 +000011353 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011355 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011356 ver = &tmp[0];
11357 }
11358
11359 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011360 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011361 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011362
11363 /* Add Indicator of Which Drive was Used to Boot the System */
11364 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11365 tmp[1] = ':';
11366 tmp[2] = '\0';
11367
Fred Drake4d1e64b2002-04-15 19:40:07 +000011368 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011369}
11370#endif
11371
Brian Curtin52173d42010-12-02 18:29:18 +000011372#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011373static int
Brian Curtin52173d42010-12-02 18:29:18 +000011374enable_symlink()
11375{
11376 HANDLE tok;
11377 TOKEN_PRIVILEGES tok_priv;
11378 LUID luid;
11379 int meth_idx = 0;
11380
11381 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011382 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011383
11384 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011385 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011386
11387 tok_priv.PrivilegeCount = 1;
11388 tok_priv.Privileges[0].Luid = luid;
11389 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11390
11391 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11392 sizeof(TOKEN_PRIVILEGES),
11393 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011394 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011395
Brian Curtin3b4499c2010-12-28 14:31:47 +000011396 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11397 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011398}
11399#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11400
Barry Warsaw4a342091996-12-19 23:50:02 +000011401static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011402all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011403{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011404#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011406#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011407#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011408 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011409#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011410#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011412#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011413#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011415#endif
Fred Drakec9680921999-12-13 16:37:25 +000011416#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011418#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011419#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011420 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011421#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011422#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011424#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011425#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011427#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011428#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011430#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011431#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011433#endif
11434#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011435 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011436#endif
11437#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011438 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011439#endif
11440#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011442#endif
11443#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011444 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011445#endif
11446#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011447 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011448#endif
11449#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011450 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011451#endif
11452#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011453 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011454#endif
11455#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011456 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011457#endif
11458#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011459 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011460#endif
11461#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011462 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011463#endif
11464#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011465 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011466#endif
11467#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011468 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011469#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011470#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011472#endif
11473#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011475#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011476#ifdef O_XATTR
11477 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11478#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011479#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011481#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011482#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011484#endif
11485#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011487#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011488#ifdef O_EXEC
11489 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11490#endif
11491#ifdef O_SEARCH
11492 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11493#endif
11494#ifdef O_TTY_INIT
11495 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11496#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011497#ifdef PRIO_PROCESS
11498 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11499#endif
11500#ifdef PRIO_PGRP
11501 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11502#endif
11503#ifdef PRIO_USER
11504 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11505#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011506#ifdef O_CLOEXEC
11507 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11508#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011509#ifdef O_ACCMODE
11510 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11511#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011512
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011513
Jesus Cea94363612012-06-22 18:32:07 +020011514#ifdef SEEK_HOLE
11515 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11516#endif
11517#ifdef SEEK_DATA
11518 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11519#endif
11520
Tim Peters5aa91602002-01-30 05:46:57 +000011521/* MS Windows */
11522#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011523 /* Don't inherit in child processes. */
11524 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011525#endif
11526#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011527 /* Optimize for short life (keep in memory). */
11528 /* MS forgot to define this one with a non-underscore form too. */
11529 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011530#endif
11531#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011532 /* Automatically delete when last handle is closed. */
11533 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011534#endif
11535#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011536 /* Optimize for random access. */
11537 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011538#endif
11539#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011540 /* Optimize for sequential access. */
11541 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011542#endif
11543
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011544/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011545#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 /* Send a SIGIO signal whenever input or output
11547 becomes available on file descriptor */
11548 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011549#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011550#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 /* Direct disk access. */
11552 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011553#endif
11554#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 /* Must be a directory. */
11556 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011557#endif
11558#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011559 /* Do not follow links. */
11560 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011561#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011562#ifdef O_NOLINKS
11563 /* Fails if link count of the named file is greater than 1 */
11564 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11565#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011566#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 /* Do not update the access time. */
11568 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011569#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011570
Victor Stinner8c62be82010-05-06 00:08:46 +000011571 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011572#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011574#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011575#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011576 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011577#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011578#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011579 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011580#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011581#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011583#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011584#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011585 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011586#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011587#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011589#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011590#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011591 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011592#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011593#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011595#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011596#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011597 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011598#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011599#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011601#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011602#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011603 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011604#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011605#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011606 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011607#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011608#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011609 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011610#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011611#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011612 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011613#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011614#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011615 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011616#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011617#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011618 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011619#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011620#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011621 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011622#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011623
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011624 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011625#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011626 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011627#endif /* ST_RDONLY */
11628#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011629 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011630#endif /* ST_NOSUID */
11631
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011632 /* FreeBSD sendfile() constants */
11633#ifdef SF_NODISKIO
11634 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11635#endif
11636#ifdef SF_MNOWAIT
11637 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11638#endif
11639#ifdef SF_SYNC
11640 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11641#endif
11642
Ross Lagerwall7807c352011-03-17 20:20:30 +020011643 /* constants for posix_fadvise */
11644#ifdef POSIX_FADV_NORMAL
11645 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11646#endif
11647#ifdef POSIX_FADV_SEQUENTIAL
11648 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11649#endif
11650#ifdef POSIX_FADV_RANDOM
11651 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11652#endif
11653#ifdef POSIX_FADV_NOREUSE
11654 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11655#endif
11656#ifdef POSIX_FADV_WILLNEED
11657 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11658#endif
11659#ifdef POSIX_FADV_DONTNEED
11660 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11661#endif
11662
11663 /* constants for waitid */
11664#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11665 if (ins(d, "P_PID", (long)P_PID)) return -1;
11666 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11667 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11668#endif
11669#ifdef WEXITED
11670 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11671#endif
11672#ifdef WNOWAIT
11673 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11674#endif
11675#ifdef WSTOPPED
11676 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11677#endif
11678#ifdef CLD_EXITED
11679 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11680#endif
11681#ifdef CLD_DUMPED
11682 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11683#endif
11684#ifdef CLD_TRAPPED
11685 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11686#endif
11687#ifdef CLD_CONTINUED
11688 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11689#endif
11690
11691 /* constants for lockf */
11692#ifdef F_LOCK
11693 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11694#endif
11695#ifdef F_TLOCK
11696 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11697#endif
11698#ifdef F_ULOCK
11699 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11700#endif
11701#ifdef F_TEST
11702 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11703#endif
11704
Guido van Rossum246bc171999-02-01 23:54:31 +000011705#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011706#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011707 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11708 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11709 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11710 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11711 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11712 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11713 if (ins(d, "P_PM", (long)P_PM)) return -1;
11714 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11715 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11716 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11717 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11718 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11719 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11720 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11721 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11722 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11723 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11724 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11725 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11726 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011727#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011728 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11729 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11730 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11731 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11732 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011733#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011734#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011735
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011736#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011737 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011738 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11739 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11740#ifdef SCHED_SPORADIC
11741 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11742#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011743#ifdef SCHED_BATCH
11744 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11745#endif
11746#ifdef SCHED_IDLE
11747 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11748#endif
11749#ifdef SCHED_RESET_ON_FORK
11750 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11751#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011752#ifdef SCHED_SYS
11753 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11754#endif
11755#ifdef SCHED_IA
11756 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11757#endif
11758#ifdef SCHED_FSS
11759 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11760#endif
11761#ifdef SCHED_FX
11762 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11763#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011764#endif
11765
Benjamin Peterson9428d532011-09-14 11:45:52 -040011766#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011767 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11768 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11769 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11770#endif
11771
Victor Stinner8b905bd2011-10-25 13:34:04 +020011772#ifdef RTLD_LAZY
11773 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11774#endif
11775#ifdef RTLD_NOW
11776 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11777#endif
11778#ifdef RTLD_GLOBAL
11779 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11780#endif
11781#ifdef RTLD_LOCAL
11782 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11783#endif
11784#ifdef RTLD_NODELETE
11785 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11786#endif
11787#ifdef RTLD_NOLOAD
11788 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11789#endif
11790#ifdef RTLD_DEEPBIND
11791 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11792#endif
11793
Guido van Rossumd48f2521997-12-05 22:19:34 +000011794#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011795 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011796#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011797 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011798}
11799
11800
Tim Peters5aa91602002-01-30 05:46:57 +000011801#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011802#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011803#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011804
11805#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011806#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011807#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011808
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011809#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011810#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011811#define MODNAME "posix"
11812#endif
11813
Martin v. Löwis1a214512008-06-11 05:26:20 +000011814static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011815 PyModuleDef_HEAD_INIT,
11816 MODNAME,
11817 posix__doc__,
11818 -1,
11819 posix_methods,
11820 NULL,
11821 NULL,
11822 NULL,
11823 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011824};
11825
11826
Larry Hastings9cf065c2012-06-22 16:30:09 -070011827static char *have_functions[] = {
11828
11829#ifdef HAVE_FACCESSAT
11830 "HAVE_FACCESSAT",
11831#endif
11832
11833#ifdef HAVE_FCHDIR
11834 "HAVE_FCHDIR",
11835#endif
11836
11837#ifdef HAVE_FCHMOD
11838 "HAVE_FCHMOD",
11839#endif
11840
11841#ifdef HAVE_FCHMODAT
11842 "HAVE_FCHMODAT",
11843#endif
11844
11845#ifdef HAVE_FCHOWN
11846 "HAVE_FCHOWN",
11847#endif
11848
11849#ifdef HAVE_FEXECVE
11850 "HAVE_FEXECVE",
11851#endif
11852
11853#ifdef HAVE_FDOPENDIR
11854 "HAVE_FDOPENDIR",
11855#endif
11856
Georg Brandl306336b2012-06-24 12:55:33 +020011857#ifdef HAVE_FPATHCONF
11858 "HAVE_FPATHCONF",
11859#endif
11860
Larry Hastings9cf065c2012-06-22 16:30:09 -070011861#ifdef HAVE_FSTATAT
11862 "HAVE_FSTATAT",
11863#endif
11864
11865#ifdef HAVE_FSTATVFS
11866 "HAVE_FSTATVFS",
11867#endif
11868
Georg Brandl306336b2012-06-24 12:55:33 +020011869#ifdef HAVE_FTRUNCATE
11870 "HAVE_FTRUNCATE",
11871#endif
11872
Larry Hastings9cf065c2012-06-22 16:30:09 -070011873#ifdef HAVE_FUTIMENS
11874 "HAVE_FUTIMENS",
11875#endif
11876
11877#ifdef HAVE_FUTIMES
11878 "HAVE_FUTIMES",
11879#endif
11880
11881#ifdef HAVE_FUTIMESAT
11882 "HAVE_FUTIMESAT",
11883#endif
11884
11885#ifdef HAVE_LINKAT
11886 "HAVE_LINKAT",
11887#endif
11888
11889#ifdef HAVE_LCHFLAGS
11890 "HAVE_LCHFLAGS",
11891#endif
11892
11893#ifdef HAVE_LCHMOD
11894 "HAVE_LCHMOD",
11895#endif
11896
11897#ifdef HAVE_LCHOWN
11898 "HAVE_LCHOWN",
11899#endif
11900
11901#ifdef HAVE_LSTAT
11902 "HAVE_LSTAT",
11903#endif
11904
11905#ifdef HAVE_LUTIMES
11906 "HAVE_LUTIMES",
11907#endif
11908
11909#ifdef HAVE_MKDIRAT
11910 "HAVE_MKDIRAT",
11911#endif
11912
11913#ifdef HAVE_MKFIFOAT
11914 "HAVE_MKFIFOAT",
11915#endif
11916
11917#ifdef HAVE_MKNODAT
11918 "HAVE_MKNODAT",
11919#endif
11920
11921#ifdef HAVE_OPENAT
11922 "HAVE_OPENAT",
11923#endif
11924
11925#ifdef HAVE_READLINKAT
11926 "HAVE_READLINKAT",
11927#endif
11928
11929#ifdef HAVE_RENAMEAT
11930 "HAVE_RENAMEAT",
11931#endif
11932
11933#ifdef HAVE_SYMLINKAT
11934 "HAVE_SYMLINKAT",
11935#endif
11936
11937#ifdef HAVE_UNLINKAT
11938 "HAVE_UNLINKAT",
11939#endif
11940
11941#ifdef HAVE_UTIMENSAT
11942 "HAVE_UTIMENSAT",
11943#endif
11944
11945#ifdef MS_WINDOWS
11946 "MS_WINDOWS",
11947#endif
11948
11949 NULL
11950};
11951
11952
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011953PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011954INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011955{
Victor Stinner8c62be82010-05-06 00:08:46 +000011956 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011957 PyObject *list;
11958 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011959
Brian Curtin52173d42010-12-02 18:29:18 +000011960#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011961 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011962#endif
11963
Victor Stinner8c62be82010-05-06 00:08:46 +000011964 m = PyModule_Create(&posixmodule);
11965 if (m == NULL)
11966 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011967
Victor Stinner8c62be82010-05-06 00:08:46 +000011968 /* Initialize environ dictionary */
11969 v = convertenviron();
11970 Py_XINCREF(v);
11971 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11972 return NULL;
11973 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011974
Victor Stinner8c62be82010-05-06 00:08:46 +000011975 if (all_ins(m))
11976 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011977
Victor Stinner8c62be82010-05-06 00:08:46 +000011978 if (setup_confname_tables(m))
11979 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011980
Victor Stinner8c62be82010-05-06 00:08:46 +000011981 Py_INCREF(PyExc_OSError);
11982 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011983
Benjamin Peterson2740af82011-08-02 17:41:34 -050011984#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011985 if (PyType_Ready(&cpu_set_type) < 0)
11986 return NULL;
11987 Py_INCREF(&cpu_set_type);
11988 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011989#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011990
Guido van Rossumb3d39562000-01-31 18:41:26 +000011991#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011992 if (posix_putenv_garbage == NULL)
11993 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011994#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011995
Victor Stinner8c62be82010-05-06 00:08:46 +000011996 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011997#if defined(HAVE_WAITID) && !defined(__APPLE__)
11998 waitid_result_desc.name = MODNAME ".waitid_result";
11999 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
12000#endif
12001
Victor Stinner8c62be82010-05-06 00:08:46 +000012002 stat_result_desc.name = MODNAME ".stat_result";
12003 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12004 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12005 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
12006 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
12007 structseq_new = StatResultType.tp_new;
12008 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012009
Victor Stinner8c62be82010-05-06 00:08:46 +000012010 statvfs_result_desc.name = MODNAME ".statvfs_result";
12011 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012012#ifdef NEED_TICKS_PER_SECOND
12013# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012014 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012015# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012016 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012017# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012018 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012019# endif
12020#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012021
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012022#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012023 sched_param_desc.name = MODNAME ".sched_param";
12024 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
12025 SchedParamType.tp_new = sched_param_new;
12026#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012027
12028 /* initialize TerminalSize_info */
12029 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
12030 Py_INCREF(&TerminalSizeType);
Victor Stinner8c62be82010-05-06 00:08:46 +000012031 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012032#if defined(HAVE_WAITID) && !defined(__APPLE__)
12033 Py_INCREF((PyObject*) &WaitidResultType);
12034 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12035#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012036 Py_INCREF((PyObject*) &StatResultType);
12037 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12038 Py_INCREF((PyObject*) &StatVFSResultType);
12039 PyModule_AddObject(m, "statvfs_result",
12040 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012041
12042#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012043 Py_INCREF(&SchedParamType);
12044 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012045#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012046
Larry Hastings605a62d2012-06-24 04:33:36 -070012047 times_result_desc.name = MODNAME ".times_result";
12048 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
12049 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12050
12051 uname_result_desc.name = MODNAME ".uname_result";
12052 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
12053 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12054
Thomas Wouters477c8d52006-05-27 19:21:47 +000012055#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012056 /*
12057 * Step 2 of weak-linking support on Mac OS X.
12058 *
12059 * The code below removes functions that are not available on the
12060 * currently active platform.
12061 *
12062 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012063 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012064 * OSX 10.4.
12065 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012066#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012067 if (fstatvfs == NULL) {
12068 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12069 return NULL;
12070 }
12071 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012072#endif /* HAVE_FSTATVFS */
12073
12074#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012075 if (statvfs == NULL) {
12076 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12077 return NULL;
12078 }
12079 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012080#endif /* HAVE_STATVFS */
12081
12082# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012083 if (lchown == NULL) {
12084 if (PyObject_DelAttrString(m, "lchown") == -1) {
12085 return NULL;
12086 }
12087 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012088#endif /* HAVE_LCHOWN */
12089
12090
12091#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012092
12093 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12094
Larry Hastings6fe20b32012-04-19 15:07:49 -070012095 billion = PyLong_FromLong(1000000000);
12096 if (!billion)
12097 return NULL;
12098
Larry Hastings9cf065c2012-06-22 16:30:09 -070012099 /* suppress "function not used" warnings */
12100 {
12101 int ignored;
12102 fd_specified("", -1);
12103 follow_symlinks_specified("", 1);
12104 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12105 dir_fd_converter(Py_None, &ignored);
12106 dir_fd_unavailable(Py_None, &ignored);
12107 }
12108
12109 /*
12110 * provide list of locally available functions
12111 * so os.py can populate support_* lists
12112 */
12113 list = PyList_New(0);
12114 if (!list)
12115 return NULL;
12116 for (trace = have_functions; *trace; trace++) {
12117 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12118 if (!unicode)
12119 return NULL;
12120 if (PyList_Append(list, unicode))
12121 return NULL;
12122 Py_DECREF(unicode);
12123 }
12124 PyModule_AddObject(m, "_have_functions", list);
12125
12126 initialized = 1;
12127
Victor Stinner8c62be82010-05-06 00:08:46 +000012128 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000012129
Guido van Rossumb6775db1994-08-01 11:34:53 +000012130}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012131
12132#ifdef __cplusplus
12133}
12134#endif