blob: afa8b392e8cfdaffebd683218107cffd99122583 [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
382# define FSTAT win32_fstat
383# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000384#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000385# define STAT stat
386# define FSTAT fstat
387# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000388#endif
389
Tim Peters11b23062003-04-23 02:39:17 +0000390#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000391#include <sys/mkdev.h>
392#else
393#if defined(MAJOR_IN_SYSMACROS)
394#include <sys/sysmacros.h>
395#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000396#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
397#include <sys/mkdev.h>
398#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000399#endif
Fred Drake699f3522000-06-29 21:12:41 +0000400
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200401/* A helper used by a number of POSIX-only functions */
402#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000403static int
404_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000405{
406#if !defined(HAVE_LARGEFILE_SUPPORT)
407 *((off_t*)addr) = PyLong_AsLong(arg);
408#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000409 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000410#endif
411 if (PyErr_Occurred())
412 return 0;
413 return 1;
414}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200415#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000416
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000417#if defined _MSC_VER && _MSC_VER >= 1400
418/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
419 * valid and throw an assertion if it isn't.
420 * Normally, an invalid fd is likely to be a C program error and therefore
421 * an assertion can be useful, but it does contradict the POSIX standard
422 * which for write(2) states:
423 * "Otherwise, -1 shall be returned and errno set to indicate the error."
424 * "[EBADF] The fildes argument is not a valid file descriptor open for
425 * writing."
426 * Furthermore, python allows the user to enter any old integer
427 * as a fd and should merely raise a python exception on error.
428 * The Microsoft CRT doesn't provide an official way to check for the
429 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000430 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000431 * internal structures involved.
432 * The structures below must be updated for each version of visual studio
433 * according to the file internal.h in the CRT source, until MS comes
434 * up with a less hacky way to do this.
435 * (all of this is to avoid globally modifying the CRT behaviour using
436 * _set_invalid_parameter_handler() and _CrtSetReportMode())
437 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000438/* The actual size of the structure is determined at runtime.
439 * Only the first items must be present.
440 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000441typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000442 intptr_t osfhnd;
443 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000444} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000445
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000446extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000447#define IOINFO_L2E 5
448#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
449#define IOINFO_ARRAYS 64
450#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
451#define FOPEN 0x01
452#define _NO_CONSOLE_FILENO (intptr_t)-2
453
454/* This function emulates what the windows CRT does to validate file handles */
455int
456_PyVerify_fd(int fd)
457{
Victor Stinner8c62be82010-05-06 00:08:46 +0000458 const int i1 = fd >> IOINFO_L2E;
459 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000460
Antoine Pitrou22e41552010-08-15 18:07:50 +0000461 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000462
Victor Stinner8c62be82010-05-06 00:08:46 +0000463 /* Determine the actual size of the ioinfo structure,
464 * as used by the CRT loaded in memory
465 */
466 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
467 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
468 }
469 if (sizeof_ioinfo == 0) {
470 /* This should not happen... */
471 goto fail;
472 }
473
474 /* See that it isn't a special CLEAR fileno */
475 if (fd != _NO_CONSOLE_FILENO) {
476 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
477 * we check pointer validity and other info
478 */
479 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
480 /* finally, check that the file is open */
481 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
482 if (info->osfile & FOPEN) {
483 return 1;
484 }
485 }
486 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000487 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000488 errno = EBADF;
489 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000490}
491
492/* the special case of checking dup2. The target fd must be in a sensible range */
493static int
494_PyVerify_fd_dup2(int fd1, int fd2)
495{
Victor Stinner8c62be82010-05-06 00:08:46 +0000496 if (!_PyVerify_fd(fd1))
497 return 0;
498 if (fd2 == _NO_CONSOLE_FILENO)
499 return 0;
500 if ((unsigned)fd2 < _NHANDLE_)
501 return 1;
502 else
503 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000504}
505#else
506/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
507#define _PyVerify_fd_dup2(A, B) (1)
508#endif
509
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000510#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000511/* The following structure was copied from
512 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
513 include doesn't seem to be present in the Windows SDK (at least as included
514 with Visual Studio Express). */
515typedef struct _REPARSE_DATA_BUFFER {
516 ULONG ReparseTag;
517 USHORT ReparseDataLength;
518 USHORT Reserved;
519 union {
520 struct {
521 USHORT SubstituteNameOffset;
522 USHORT SubstituteNameLength;
523 USHORT PrintNameOffset;
524 USHORT PrintNameLength;
525 ULONG Flags;
526 WCHAR PathBuffer[1];
527 } SymbolicLinkReparseBuffer;
528
529 struct {
530 USHORT SubstituteNameOffset;
531 USHORT SubstituteNameLength;
532 USHORT PrintNameOffset;
533 USHORT PrintNameLength;
534 WCHAR PathBuffer[1];
535 } MountPointReparseBuffer;
536
537 struct {
538 UCHAR DataBuffer[1];
539 } GenericReparseBuffer;
540 };
541} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
542
543#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
544 GenericReparseBuffer)
545#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
546
547static int
Brian Curtind25aef52011-06-13 15:16:04 -0500548win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000549{
550 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
551 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
552 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000553
554 if (0 == DeviceIoControl(
555 reparse_point_handle,
556 FSCTL_GET_REPARSE_POINT,
557 NULL, 0, /* in buffer */
558 target_buffer, sizeof(target_buffer),
559 &n_bytes_returned,
560 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500561 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000562
563 if (reparse_tag)
564 *reparse_tag = rdb->ReparseTag;
565
Brian Curtind25aef52011-06-13 15:16:04 -0500566 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000567}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100568
569static int
570win32_warn_bytes_api()
571{
572 return PyErr_WarnEx(PyExc_DeprecationWarning,
573 "The Windows bytes API has been deprecated, "
574 "use Unicode filenames instead",
575 1);
576}
577
578static PyObject*
579win32_decode_filename(PyObject *obj)
580{
581 PyObject *unicode;
582 if (PyUnicode_Check(obj)) {
583 if (PyUnicode_READY(obj))
584 return NULL;
585 Py_INCREF(obj);
586 return obj;
587 }
588 if (!PyUnicode_FSDecoder(obj, &unicode))
589 return NULL;
590 if (win32_warn_bytes_api()) {
591 Py_DECREF(unicode);
592 return NULL;
593 }
594 return unicode;
595}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000596#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000597
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000598/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000599#ifdef WITH_NEXT_FRAMEWORK
600/* On Darwin/MacOSX a shared library or framework has no access to
601** environ directly, we must obtain it with _NSGetEnviron().
602*/
603#include <crt_externs.h>
604static char **environ;
605#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000606extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000607#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000608
Barry Warsaw53699e91996-12-10 23:23:01 +0000609static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000610convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000611{
Victor Stinner8c62be82010-05-06 00:08:46 +0000612 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000613#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000614 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000615#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000616 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000617#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000618#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000619 APIRET rc;
620 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
621#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000622
Victor Stinner8c62be82010-05-06 00:08:46 +0000623 d = PyDict_New();
624 if (d == NULL)
625 return NULL;
626#ifdef WITH_NEXT_FRAMEWORK
627 if (environ == NULL)
628 environ = *_NSGetEnviron();
629#endif
630#ifdef MS_WINDOWS
631 /* _wenviron must be initialized in this way if the program is started
632 through main() instead of wmain(). */
633 _wgetenv(L"");
634 if (_wenviron == NULL)
635 return d;
636 /* This part ignores errors */
637 for (e = _wenviron; *e != NULL; e++) {
638 PyObject *k;
639 PyObject *v;
640 wchar_t *p = wcschr(*e, L'=');
641 if (p == NULL)
642 continue;
643 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
644 if (k == NULL) {
645 PyErr_Clear();
646 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000647 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000648 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
649 if (v == NULL) {
650 PyErr_Clear();
651 Py_DECREF(k);
652 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000653 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000654 if (PyDict_GetItem(d, k) == NULL) {
655 if (PyDict_SetItem(d, k, v) != 0)
656 PyErr_Clear();
657 }
658 Py_DECREF(k);
659 Py_DECREF(v);
660 }
661#else
662 if (environ == NULL)
663 return d;
664 /* This part ignores errors */
665 for (e = environ; *e != NULL; e++) {
666 PyObject *k;
667 PyObject *v;
668 char *p = strchr(*e, '=');
669 if (p == NULL)
670 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000671 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000672 if (k == NULL) {
673 PyErr_Clear();
674 continue;
675 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000676 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000677 if (v == NULL) {
678 PyErr_Clear();
679 Py_DECREF(k);
680 continue;
681 }
682 if (PyDict_GetItem(d, k) == NULL) {
683 if (PyDict_SetItem(d, k, v) != 0)
684 PyErr_Clear();
685 }
686 Py_DECREF(k);
687 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000688 }
689#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000690#if defined(PYOS_OS2)
691 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
692 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
693 PyObject *v = PyBytes_FromString(buffer);
694 PyDict_SetItemString(d, "BEGINLIBPATH", v);
695 Py_DECREF(v);
696 }
697 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
698 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
699 PyObject *v = PyBytes_FromString(buffer);
700 PyDict_SetItemString(d, "ENDLIBPATH", v);
701 Py_DECREF(v);
702 }
703#endif
704 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000705}
706
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000707/* Set a POSIX-specific error from errno, and return NULL */
708
Barry Warsawd58d7641998-07-23 16:14:40 +0000709static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000710posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000711{
Victor Stinner8c62be82010-05-06 00:08:46 +0000712 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000713}
Barry Warsawd58d7641998-07-23 16:14:40 +0000714static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000715posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000716{
Victor Stinner8c62be82010-05-06 00:08:46 +0000717 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000718}
719
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000720
Mark Hammondef8b6542001-05-13 08:04:26 +0000721static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000722posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000723{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000724 PyObject *name_str, *rc;
725 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
726 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000727 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000728 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
729 name_str);
730 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000731 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000732}
733
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000734#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000735static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000736win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000737{
Victor Stinner8c62be82010-05-06 00:08:46 +0000738 /* XXX We should pass the function name along in the future.
739 (winreg.c also wants to pass the function name.)
740 This would however require an additional param to the
741 Windows error object, which is non-trivial.
742 */
743 errno = GetLastError();
744 if (filename)
745 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
746 else
747 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000748}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000749
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000750static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +0200751win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000752{
Victor Stinner8c62be82010-05-06 00:08:46 +0000753 /* XXX - see win32_error for comments on 'function' */
754 errno = GetLastError();
755 if (filename)
756 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
757 else
758 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000759}
760
Victor Stinnereb5657a2011-09-30 01:44:27 +0200761static PyObject *
762win32_error_object(char* function, PyObject* filename)
763{
764 /* XXX - see win32_error for comments on 'function' */
765 errno = GetLastError();
766 if (filename)
767 return PyErr_SetExcFromWindowsErrWithFilenameObject(
768 PyExc_WindowsError,
769 errno,
770 filename);
771 else
772 return PyErr_SetFromWindowsErr(errno);
773}
774
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000775#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776
Guido van Rossumd48f2521997-12-05 22:19:34 +0000777#if defined(PYOS_OS2)
778/**********************************************************************
779 * Helper Function to Trim and Format OS/2 Messages
780 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000781static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000782os2_formatmsg(char *msgbuf, int msglen, char *reason)
783{
784 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
785
786 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
787 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
788
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000789 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000790 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
791 }
792
793 /* Add Optional Reason Text */
794 if (reason) {
795 strcat(msgbuf, " : ");
796 strcat(msgbuf, reason);
797 }
798}
799
800/**********************************************************************
801 * Decode an OS/2 Operating System Error Code
802 *
803 * A convenience function to lookup an OS/2 error code and return a
804 * text message we can use to raise a Python exception.
805 *
806 * Notes:
807 * The messages for errors returned from the OS/2 kernel reside in
808 * the file OSO001.MSG in the \OS2 directory hierarchy.
809 *
810 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000811static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000812os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
813{
814 APIRET rc;
815 ULONG msglen;
816
817 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
818 Py_BEGIN_ALLOW_THREADS
819 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
820 errorcode, "oso001.msg", &msglen);
821 Py_END_ALLOW_THREADS
822
823 if (rc == NO_ERROR)
824 os2_formatmsg(msgbuf, msglen, reason);
825 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000826 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000827 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000828
829 return msgbuf;
830}
831
832/* Set an OS/2-specific error and return NULL. OS/2 kernel
833 errors are not in a global variable e.g. 'errno' nor are
834 they congruent with posix error numbers. */
835
Victor Stinner8c62be82010-05-06 00:08:46 +0000836static PyObject *
837os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000838{
839 char text[1024];
840 PyObject *v;
841
842 os2_strerror(text, sizeof(text), code, "");
843
844 v = Py_BuildValue("(is)", code, text);
845 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000846 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000847 Py_DECREF(v);
848 }
849 return NULL; /* Signal to Python that an Exception is Pending */
850}
851
852#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000853
854/* POSIX generic methods */
855
Barry Warsaw53699e91996-12-10 23:23:01 +0000856static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000857posix_fildes(PyObject *fdobj, int (*func)(int))
858{
Victor Stinner8c62be82010-05-06 00:08:46 +0000859 int fd;
860 int res;
861 fd = PyObject_AsFileDescriptor(fdobj);
862 if (fd < 0)
863 return NULL;
864 if (!_PyVerify_fd(fd))
865 return posix_error();
866 Py_BEGIN_ALLOW_THREADS
867 res = (*func)(fd);
868 Py_END_ALLOW_THREADS
869 if (res < 0)
870 return posix_error();
871 Py_INCREF(Py_None);
872 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000873}
Guido van Rossum21142a01999-01-08 21:05:37 +0000874
875static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000876posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000877{
Victor Stinner8c62be82010-05-06 00:08:46 +0000878 PyObject *opath1 = NULL;
879 char *path1;
880 int res;
881 if (!PyArg_ParseTuple(args, format,
882 PyUnicode_FSConverter, &opath1))
883 return NULL;
884 path1 = PyBytes_AsString(opath1);
885 Py_BEGIN_ALLOW_THREADS
886 res = (*func)(path1);
887 Py_END_ALLOW_THREADS
888 if (res < 0)
889 return posix_error_with_allocated_filename(opath1);
890 Py_DECREF(opath1);
891 Py_INCREF(Py_None);
892 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000893}
894
Barry Warsaw53699e91996-12-10 23:23:01 +0000895static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000896posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000897 char *format,
898 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000899{
Victor Stinner8c62be82010-05-06 00:08:46 +0000900 PyObject *opath1 = NULL, *opath2 = NULL;
901 char *path1, *path2;
902 int res;
903 if (!PyArg_ParseTuple(args, format,
904 PyUnicode_FSConverter, &opath1,
905 PyUnicode_FSConverter, &opath2)) {
906 return NULL;
907 }
908 path1 = PyBytes_AsString(opath1);
909 path2 = PyBytes_AsString(opath2);
910 Py_BEGIN_ALLOW_THREADS
911 res = (*func)(path1, path2);
912 Py_END_ALLOW_THREADS
913 Py_DECREF(opath1);
914 Py_DECREF(opath2);
915 if (res != 0)
916 /* XXX how to report both path1 and path2??? */
917 return posix_error();
918 Py_INCREF(Py_None);
919 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920}
921
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000922#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000923static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000924win32_1str(PyObject* args, char* func,
925 char* format, BOOL (__stdcall *funcA)(LPCSTR),
926 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000927{
Victor Stinner8c62be82010-05-06 00:08:46 +0000928 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100929 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +0000930 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000931
Victor Stinnereb5657a2011-09-30 01:44:27 +0200932 if (PyArg_ParseTuple(args, wformat, &uni))
933 {
934 wchar_t *wstr = PyUnicode_AsUnicode(uni);
935 if (wstr == NULL)
936 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000937 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +0200938 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +0000939 Py_END_ALLOW_THREADS
940 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +0200941 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +0000942 Py_INCREF(Py_None);
943 return Py_None;
944 }
Victor Stinnereb5657a2011-09-30 01:44:27 +0200945 PyErr_Clear();
946
Victor Stinner8c62be82010-05-06 00:08:46 +0000947 if (!PyArg_ParseTuple(args, format, &ansi))
948 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100949 if (win32_warn_bytes_api())
950 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000951 Py_BEGIN_ALLOW_THREADS
952 result = funcA(ansi);
953 Py_END_ALLOW_THREADS
954 if (!result)
955 return win32_error(func, ansi);
956 Py_INCREF(Py_None);
957 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000958
959}
960
961/* This is a reimplementation of the C library's chdir function,
962 but one that produces Win32 errors instead of DOS error codes.
963 chdir is essentially a wrapper around SetCurrentDirectory; however,
964 it also needs to set "magic" environment variables indicating
965 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000966static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000967win32_chdir(LPCSTR path)
968{
Victor Stinner8c62be82010-05-06 00:08:46 +0000969 char new_path[MAX_PATH+1];
970 int result;
971 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000972
Victor Stinner8c62be82010-05-06 00:08:46 +0000973 if(!SetCurrentDirectoryA(path))
974 return FALSE;
975 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
976 if (!result)
977 return FALSE;
978 /* In the ANSI API, there should not be any paths longer
979 than MAX_PATH. */
980 assert(result <= MAX_PATH+1);
981 if (strncmp(new_path, "\\\\", 2) == 0 ||
982 strncmp(new_path, "//", 2) == 0)
983 /* UNC path, nothing to do. */
984 return TRUE;
985 env[1] = new_path[0];
986 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000987}
988
989/* The Unicode version differs from the ANSI version
990 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000991static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000992win32_wchdir(LPCWSTR path)
993{
Victor Stinner8c62be82010-05-06 00:08:46 +0000994 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
995 int result;
996 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000997
Victor Stinner8c62be82010-05-06 00:08:46 +0000998 if(!SetCurrentDirectoryW(path))
999 return FALSE;
1000 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1001 if (!result)
1002 return FALSE;
1003 if (result > MAX_PATH+1) {
1004 new_path = malloc(result * sizeof(wchar_t));
1005 if (!new_path) {
1006 SetLastError(ERROR_OUTOFMEMORY);
1007 return FALSE;
1008 }
1009 result = GetCurrentDirectoryW(result, new_path);
1010 if (!result) {
1011 free(new_path);
1012 return FALSE;
1013 }
1014 }
1015 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1016 wcsncmp(new_path, L"//", 2) == 0)
1017 /* UNC path, nothing to do. */
1018 return TRUE;
1019 env[1] = new_path[0];
1020 result = SetEnvironmentVariableW(env, new_path);
1021 if (new_path != _new_path)
1022 free(new_path);
1023 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001024}
1025#endif
1026
Martin v. Löwis14694662006-02-03 12:54:16 +00001027#ifdef MS_WINDOWS
1028/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1029 - time stamps are restricted to second resolution
1030 - file modification times suffer from forth-and-back conversions between
1031 UTC and local time
1032 Therefore, we implement our own stat, based on the Win32 API directly.
1033*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001034#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001035
1036struct win32_stat{
1037 int st_dev;
1038 __int64 st_ino;
1039 unsigned short st_mode;
1040 int st_nlink;
1041 int st_uid;
1042 int st_gid;
1043 int st_rdev;
1044 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001045 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001046 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001047 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001048 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001049 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001050 int st_ctime_nsec;
1051};
1052
1053static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1054
1055static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001056FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001057{
Victor Stinner8c62be82010-05-06 00:08:46 +00001058 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1059 /* Cannot simply cast and dereference in_ptr,
1060 since it might not be aligned properly */
1061 __int64 in;
1062 memcpy(&in, in_ptr, sizeof(in));
1063 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001064 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001065}
1066
Thomas Wouters477c8d52006-05-27 19:21:47 +00001067static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001068time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001069{
Victor Stinner8c62be82010-05-06 00:08:46 +00001070 /* XXX endianness */
1071 __int64 out;
1072 out = time_in + secs_between_epochs;
1073 out = out * 10000000 + nsec_in / 100;
1074 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001075}
1076
Martin v. Löwis14694662006-02-03 12:54:16 +00001077/* Below, we *know* that ugo+r is 0444 */
1078#if _S_IREAD != 0400
1079#error Unsupported C library
1080#endif
1081static int
1082attributes_to_mode(DWORD attr)
1083{
Victor Stinner8c62be82010-05-06 00:08:46 +00001084 int m = 0;
1085 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1086 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1087 else
1088 m |= _S_IFREG;
1089 if (attr & FILE_ATTRIBUTE_READONLY)
1090 m |= 0444;
1091 else
1092 m |= 0666;
1093 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001094}
1095
1096static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001097attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001098{
Victor Stinner8c62be82010-05-06 00:08:46 +00001099 memset(result, 0, sizeof(*result));
1100 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1101 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1102 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1103 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1104 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001105 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001106 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001107 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1108 /* first clear the S_IFMT bits */
1109 result->st_mode ^= (result->st_mode & 0170000);
1110 /* now set the bits that make this a symlink */
1111 result->st_mode |= 0120000;
1112 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001113
Victor Stinner8c62be82010-05-06 00:08:46 +00001114 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001115}
1116
Guido van Rossumd8faa362007-04-27 19:54:29 +00001117static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001118attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001119{
Victor Stinner8c62be82010-05-06 00:08:46 +00001120 HANDLE hFindFile;
1121 WIN32_FIND_DATAA FileData;
1122 hFindFile = FindFirstFileA(pszFile, &FileData);
1123 if (hFindFile == INVALID_HANDLE_VALUE)
1124 return FALSE;
1125 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001126 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001127 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001128 info->dwFileAttributes = FileData.dwFileAttributes;
1129 info->ftCreationTime = FileData.ftCreationTime;
1130 info->ftLastAccessTime = FileData.ftLastAccessTime;
1131 info->ftLastWriteTime = FileData.ftLastWriteTime;
1132 info->nFileSizeHigh = FileData.nFileSizeHigh;
1133 info->nFileSizeLow = FileData.nFileSizeLow;
1134/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001135 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1136 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001137 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001138}
1139
1140static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001141attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001142{
Victor Stinner8c62be82010-05-06 00:08:46 +00001143 HANDLE hFindFile;
1144 WIN32_FIND_DATAW FileData;
1145 hFindFile = FindFirstFileW(pszFile, &FileData);
1146 if (hFindFile == INVALID_HANDLE_VALUE)
1147 return FALSE;
1148 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001149 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001150 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001151 info->dwFileAttributes = FileData.dwFileAttributes;
1152 info->ftCreationTime = FileData.ftCreationTime;
1153 info->ftLastAccessTime = FileData.ftLastAccessTime;
1154 info->ftLastWriteTime = FileData.ftLastWriteTime;
1155 info->nFileSizeHigh = FileData.nFileSizeHigh;
1156 info->nFileSizeLow = FileData.nFileSizeLow;
1157/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001158 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1159 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001160 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001161}
1162
Brian Curtind25aef52011-06-13 15:16:04 -05001163/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1164static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001165static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1166 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001167static int
Brian Curtind25aef52011-06-13 15:16:04 -05001168check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001169{
Brian Curtind25aef52011-06-13 15:16:04 -05001170 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001171 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1172 DWORD);
1173
Brian Curtind25aef52011-06-13 15:16:04 -05001174 /* only recheck */
1175 if (!has_GetFinalPathNameByHandle)
1176 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001177 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001178 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1179 "GetFinalPathNameByHandleA");
1180 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1181 "GetFinalPathNameByHandleW");
1182 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1183 Py_GetFinalPathNameByHandleW;
1184 }
1185 return has_GetFinalPathNameByHandle;
1186}
1187
1188static BOOL
1189get_target_path(HANDLE hdl, wchar_t **target_path)
1190{
1191 int buf_size, result_length;
1192 wchar_t *buf;
1193
1194 /* We have a good handle to the target, use it to determine
1195 the target path name (then we'll call lstat on it). */
1196 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1197 VOLUME_NAME_DOS);
1198 if(!buf_size)
1199 return FALSE;
1200
1201 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001202 if (!buf) {
1203 SetLastError(ERROR_OUTOFMEMORY);
1204 return FALSE;
1205 }
1206
Brian Curtind25aef52011-06-13 15:16:04 -05001207 result_length = Py_GetFinalPathNameByHandleW(hdl,
1208 buf, buf_size, VOLUME_NAME_DOS);
1209
1210 if(!result_length) {
1211 free(buf);
1212 return FALSE;
1213 }
1214
1215 if(!CloseHandle(hdl)) {
1216 free(buf);
1217 return FALSE;
1218 }
1219
1220 buf[result_length] = 0;
1221
1222 *target_path = buf;
1223 return TRUE;
1224}
1225
1226static int
1227win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1228 BOOL traverse);
1229static int
1230win32_xstat_impl(const char *path, struct win32_stat *result,
1231 BOOL traverse)
1232{
Victor Stinner26de69d2011-06-17 15:15:38 +02001233 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001234 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001235 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001236 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001237 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001238 const char *dot;
1239
Brian Curtind25aef52011-06-13 15:16:04 -05001240 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001241 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1242 traverse reparse point. */
1243 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001244 }
1245
Brian Curtinf5e76d02010-11-24 13:14:05 +00001246 hFile = CreateFileA(
1247 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001248 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001249 0, /* share mode */
1250 NULL, /* security attributes */
1251 OPEN_EXISTING,
1252 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001253 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1254 Because of this, calls like GetFinalPathNameByHandle will return
1255 the symlink path agin and not the actual final path. */
1256 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1257 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001258 NULL);
1259
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001260 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001261 /* Either the target doesn't exist, or we don't have access to
1262 get a handle to it. If the former, we need to return an error.
1263 If the latter, we can use attributes_from_dir. */
1264 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001265 return -1;
1266 /* Could not get attributes on open file. Fall back to
1267 reading the directory. */
1268 if (!attributes_from_dir(path, &info, &reparse_tag))
1269 /* Very strange. This should not fail now */
1270 return -1;
1271 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1272 if (traverse) {
1273 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001274 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001275 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001276 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001277 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001278 } else {
1279 if (!GetFileInformationByHandle(hFile, &info)) {
1280 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001281 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001282 }
1283 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001284 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1285 return -1;
1286
1287 /* Close the outer open file handle now that we're about to
1288 reopen it with different flags. */
1289 if (!CloseHandle(hFile))
1290 return -1;
1291
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001292 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001293 /* In order to call GetFinalPathNameByHandle we need to open
1294 the file without the reparse handling flag set. */
1295 hFile2 = CreateFileA(
1296 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1297 NULL, OPEN_EXISTING,
1298 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1299 NULL);
1300 if (hFile2 == INVALID_HANDLE_VALUE)
1301 return -1;
1302
1303 if (!get_target_path(hFile2, &target_path))
1304 return -1;
1305
1306 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001307 free(target_path);
1308 return code;
1309 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001310 } else
1311 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001312 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001313 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001314
1315 /* Set S_IEXEC if it is an .exe, .bat, ... */
1316 dot = strrchr(path, '.');
1317 if (dot) {
1318 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1319 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1320 result->st_mode |= 0111;
1321 }
1322 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001323}
1324
1325static int
Brian Curtind25aef52011-06-13 15:16:04 -05001326win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1327 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001328{
1329 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001330 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001331 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001332 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001333 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001334 const wchar_t *dot;
1335
Brian Curtind25aef52011-06-13 15:16:04 -05001336 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001337 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1338 traverse reparse point. */
1339 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001340 }
1341
Brian Curtinf5e76d02010-11-24 13:14:05 +00001342 hFile = CreateFileW(
1343 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001344 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001345 0, /* share mode */
1346 NULL, /* security attributes */
1347 OPEN_EXISTING,
1348 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001349 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1350 Because of this, calls like GetFinalPathNameByHandle will return
1351 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001352 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001353 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001354 NULL);
1355
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001356 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001357 /* Either the target doesn't exist, or we don't have access to
1358 get a handle to it. If the former, we need to return an error.
1359 If the latter, we can use attributes_from_dir. */
1360 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001361 return -1;
1362 /* Could not get attributes on open file. Fall back to
1363 reading the directory. */
1364 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1365 /* Very strange. This should not fail now */
1366 return -1;
1367 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1368 if (traverse) {
1369 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001370 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001371 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001372 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001373 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001374 } else {
1375 if (!GetFileInformationByHandle(hFile, &info)) {
1376 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001377 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001378 }
1379 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001380 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1381 return -1;
1382
1383 /* Close the outer open file handle now that we're about to
1384 reopen it with different flags. */
1385 if (!CloseHandle(hFile))
1386 return -1;
1387
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001388 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001389 /* In order to call GetFinalPathNameByHandle we need to open
1390 the file without the reparse handling flag set. */
1391 hFile2 = CreateFileW(
1392 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1393 NULL, OPEN_EXISTING,
1394 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1395 NULL);
1396 if (hFile2 == INVALID_HANDLE_VALUE)
1397 return -1;
1398
1399 if (!get_target_path(hFile2, &target_path))
1400 return -1;
1401
1402 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001403 free(target_path);
1404 return code;
1405 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001406 } else
1407 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001408 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001409 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001410
1411 /* Set S_IEXEC if it is an .exe, .bat, ... */
1412 dot = wcsrchr(path, '.');
1413 if (dot) {
1414 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1415 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1416 result->st_mode |= 0111;
1417 }
1418 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001419}
1420
1421static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001422win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001423{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001424 /* Protocol violation: we explicitly clear errno, instead of
1425 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001426 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001427 errno = 0;
1428 return code;
1429}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001430
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001431static int
1432win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1433{
1434 /* Protocol violation: we explicitly clear errno, instead of
1435 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001436 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001437 errno = 0;
1438 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001439}
Brian Curtind25aef52011-06-13 15:16:04 -05001440/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001441
1442 In Posix, stat automatically traverses symlinks and returns the stat
1443 structure for the target. In Windows, the equivalent GetFileAttributes by
1444 default does not traverse symlinks and instead returns attributes for
1445 the symlink.
1446
1447 Therefore, win32_lstat will get the attributes traditionally, and
1448 win32_stat will first explicitly resolve the symlink target and then will
1449 call win32_lstat on that result.
1450
Ezio Melotti4969f702011-03-15 05:59:46 +02001451 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001452
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001453static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001454win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001455{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001456 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001457}
1458
Victor Stinner8c62be82010-05-06 00:08:46 +00001459static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001460win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001461{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001462 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001463}
1464
1465static int
1466win32_stat(const char* path, struct win32_stat *result)
1467{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001468 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001469}
1470
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001471static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001472win32_stat_w(const wchar_t* path, struct win32_stat *result)
1473{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001474 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001475}
1476
1477static int
1478win32_fstat(int file_number, struct win32_stat *result)
1479{
Victor Stinner8c62be82010-05-06 00:08:46 +00001480 BY_HANDLE_FILE_INFORMATION info;
1481 HANDLE h;
1482 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001483
Victor Stinner8c62be82010-05-06 00:08:46 +00001484 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001485
Victor Stinner8c62be82010-05-06 00:08:46 +00001486 /* Protocol violation: we explicitly clear errno, instead of
1487 setting it to a POSIX error. Callers should use GetLastError. */
1488 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001489
Victor Stinner8c62be82010-05-06 00:08:46 +00001490 if (h == INVALID_HANDLE_VALUE) {
1491 /* This is really a C library error (invalid file handle).
1492 We set the Win32 error to the closes one matching. */
1493 SetLastError(ERROR_INVALID_HANDLE);
1494 return -1;
1495 }
1496 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001497
Victor Stinner8c62be82010-05-06 00:08:46 +00001498 type = GetFileType(h);
1499 if (type == FILE_TYPE_UNKNOWN) {
1500 DWORD error = GetLastError();
1501 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001502 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001503 }
1504 /* else: valid but unknown file */
1505 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001506
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 if (type != FILE_TYPE_DISK) {
1508 if (type == FILE_TYPE_CHAR)
1509 result->st_mode = _S_IFCHR;
1510 else if (type == FILE_TYPE_PIPE)
1511 result->st_mode = _S_IFIFO;
1512 return 0;
1513 }
1514
1515 if (!GetFileInformationByHandle(h, &info)) {
1516 return -1;
1517 }
1518
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001519 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001521 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1522 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001523}
1524
1525#endif /* MS_WINDOWS */
1526
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001527PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001528"stat_result: Result from stat or lstat.\n\n\
1529This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001530 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001531or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1532\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001533Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1534or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001535\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001536See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001537
1538static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001539 {"st_mode", "protection bits"},
1540 {"st_ino", "inode"},
1541 {"st_dev", "device"},
1542 {"st_nlink", "number of hard links"},
1543 {"st_uid", "user ID of owner"},
1544 {"st_gid", "group ID of owner"},
1545 {"st_size", "total size, in bytes"},
1546 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1547 {NULL, "integer time of last access"},
1548 {NULL, "integer time of last modification"},
1549 {NULL, "integer time of last change"},
1550 {"st_atime", "time of last access"},
1551 {"st_mtime", "time of last modification"},
1552 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001553 {"st_atime_ns", "time of last access in nanoseconds"},
1554 {"st_mtime_ns", "time of last modification in nanoseconds"},
1555 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001556#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001557 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001558#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001559#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001561#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001562#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001563 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001564#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001565#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001566 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001567#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001568#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001570#endif
1571#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001572 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001573#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001574 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001575};
1576
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001577#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001578#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001579#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001580#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001581#endif
1582
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001583#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001584#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1585#else
1586#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1587#endif
1588
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001589#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001590#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1591#else
1592#define ST_RDEV_IDX ST_BLOCKS_IDX
1593#endif
1594
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001595#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1596#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1597#else
1598#define ST_FLAGS_IDX ST_RDEV_IDX
1599#endif
1600
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001601#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001602#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001603#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001604#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001605#endif
1606
1607#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1608#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1609#else
1610#define ST_BIRTHTIME_IDX ST_GEN_IDX
1611#endif
1612
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001613static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001614 "stat_result", /* name */
1615 stat_result__doc__, /* doc */
1616 stat_result_fields,
1617 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001618};
1619
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001620PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001621"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1622This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001623 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001624or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001625\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001626See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001627
1628static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001629 {"f_bsize", },
1630 {"f_frsize", },
1631 {"f_blocks", },
1632 {"f_bfree", },
1633 {"f_bavail", },
1634 {"f_files", },
1635 {"f_ffree", },
1636 {"f_favail", },
1637 {"f_flag", },
1638 {"f_namemax",},
1639 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001640};
1641
1642static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001643 "statvfs_result", /* name */
1644 statvfs_result__doc__, /* doc */
1645 statvfs_result_fields,
1646 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001647};
1648
Ross Lagerwall7807c352011-03-17 20:20:30 +02001649#if defined(HAVE_WAITID) && !defined(__APPLE__)
1650PyDoc_STRVAR(waitid_result__doc__,
1651"waitid_result: Result from waitid.\n\n\
1652This object may be accessed either as a tuple of\n\
1653 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1654or via the attributes si_pid, si_uid, and so on.\n\
1655\n\
1656See os.waitid for more information.");
1657
1658static PyStructSequence_Field waitid_result_fields[] = {
1659 {"si_pid", },
1660 {"si_uid", },
1661 {"si_signo", },
1662 {"si_status", },
1663 {"si_code", },
1664 {0}
1665};
1666
1667static PyStructSequence_Desc waitid_result_desc = {
1668 "waitid_result", /* name */
1669 waitid_result__doc__, /* doc */
1670 waitid_result_fields,
1671 5
1672};
1673static PyTypeObject WaitidResultType;
1674#endif
1675
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001676static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001677static PyTypeObject StatResultType;
1678static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001679#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001680static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001681#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001682static newfunc structseq_new;
1683
1684static PyObject *
1685statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1686{
Victor Stinner8c62be82010-05-06 00:08:46 +00001687 PyStructSequence *result;
1688 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001689
Victor Stinner8c62be82010-05-06 00:08:46 +00001690 result = (PyStructSequence*)structseq_new(type, args, kwds);
1691 if (!result)
1692 return NULL;
1693 /* If we have been initialized from a tuple,
1694 st_?time might be set to None. Initialize it
1695 from the int slots. */
1696 for (i = 7; i <= 9; i++) {
1697 if (result->ob_item[i+3] == Py_None) {
1698 Py_DECREF(Py_None);
1699 Py_INCREF(result->ob_item[i]);
1700 result->ob_item[i+3] = result->ob_item[i];
1701 }
1702 }
1703 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001704}
1705
1706
1707
1708/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001709static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001710
1711PyDoc_STRVAR(stat_float_times__doc__,
1712"stat_float_times([newval]) -> oldval\n\n\
1713Determine whether os.[lf]stat represents time stamps as float objects.\n\
1714If newval is True, future calls to stat() return floats, if it is False,\n\
1715future calls return ints. \n\
1716If newval is omitted, return the current setting.\n");
1717
1718static PyObject*
1719stat_float_times(PyObject* self, PyObject *args)
1720{
Victor Stinner8c62be82010-05-06 00:08:46 +00001721 int newval = -1;
1722 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1723 return NULL;
1724 if (newval == -1)
1725 /* Return old value */
1726 return PyBool_FromLong(_stat_float_times);
1727 _stat_float_times = newval;
1728 Py_INCREF(Py_None);
1729 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001730}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001731
Larry Hastings6fe20b32012-04-19 15:07:49 -07001732static PyObject *billion = NULL;
1733
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001734static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001735fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001736{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001737 PyObject *s = _PyLong_FromTime_t(sec);
1738 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1739 PyObject *s_in_ns = NULL;
1740 PyObject *ns_total = NULL;
1741 PyObject *float_s = NULL;
1742
1743 if (!(s && ns_fractional))
1744 goto exit;
1745
1746 s_in_ns = PyNumber_Multiply(s, billion);
1747 if (!s_in_ns)
1748 goto exit;
1749
1750 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1751 if (!ns_total)
1752 goto exit;
1753
Victor Stinner4195b5c2012-02-08 23:03:19 +01001754 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001755 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1756 if (!float_s)
1757 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001759 else {
1760 float_s = s;
1761 Py_INCREF(float_s);
1762 }
1763
1764 PyStructSequence_SET_ITEM(v, index, s);
1765 PyStructSequence_SET_ITEM(v, index+3, float_s);
1766 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1767 s = NULL;
1768 float_s = NULL;
1769 ns_total = NULL;
1770exit:
1771 Py_XDECREF(s);
1772 Py_XDECREF(ns_fractional);
1773 Py_XDECREF(s_in_ns);
1774 Py_XDECREF(ns_total);
1775 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001776}
1777
Tim Peters5aa91602002-01-30 05:46:57 +00001778/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001779 (used by posix_stat() and posix_fstat()) */
1780static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001781_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001782{
Victor Stinner8c62be82010-05-06 00:08:46 +00001783 unsigned long ansec, mnsec, cnsec;
1784 PyObject *v = PyStructSequence_New(&StatResultType);
1785 if (v == NULL)
1786 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001787
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001789#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001790 PyStructSequence_SET_ITEM(v, 1,
1791 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001792#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001793 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001794#endif
1795#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001796 PyStructSequence_SET_ITEM(v, 2,
1797 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001798#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001799 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001800#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001801 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1802 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1803 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001804#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001805 PyStructSequence_SET_ITEM(v, 6,
1806 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001807#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001808 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001809#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001810
Martin v. Löwis14694662006-02-03 12:54:16 +00001811#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001812 ansec = st->st_atim.tv_nsec;
1813 mnsec = st->st_mtim.tv_nsec;
1814 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001815#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001816 ansec = st->st_atimespec.tv_nsec;
1817 mnsec = st->st_mtimespec.tv_nsec;
1818 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001819#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001820 ansec = st->st_atime_nsec;
1821 mnsec = st->st_mtime_nsec;
1822 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001823#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001824 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001825#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001826 fill_time(v, 7, st->st_atime, ansec);
1827 fill_time(v, 8, st->st_mtime, mnsec);
1828 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001829
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001830#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1832 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001833#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001834#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1836 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001837#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001838#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1840 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001841#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001842#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001843 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1844 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001845#endif
1846#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01001848 PyObject *val;
1849 unsigned long bsec,bnsec;
1850 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001851#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01001852 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001853#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01001854 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001855#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001856 if (_stat_float_times) {
1857 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1858 } else {
1859 val = PyLong_FromLong((long)bsec);
1860 }
1861 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1862 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00001863 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001864#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001865#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001866 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1867 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001868#endif
Fred Drake699f3522000-06-29 21:12:41 +00001869
Victor Stinner8c62be82010-05-06 00:08:46 +00001870 if (PyErr_Occurred()) {
1871 Py_DECREF(v);
1872 return NULL;
1873 }
Fred Drake699f3522000-06-29 21:12:41 +00001874
Victor Stinner8c62be82010-05-06 00:08:46 +00001875 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001876}
1877
Barry Warsaw53699e91996-12-10 23:23:01 +00001878static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01001879posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001880 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001881#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001882 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001883#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001884 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001885#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001886 char *wformat,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001887 int (*wstatfunc)(const wchar_t *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001888{
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 STRUCT_STAT st;
1890 PyObject *opath;
1891 char *path;
1892 int res;
1893 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001894
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001895#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001896 PyObject *po;
Victor Stinner4195b5c2012-02-08 23:03:19 +01001897 if (PyArg_ParseTuple(args, wformat, &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001898 wchar_t *wpath = PyUnicode_AsUnicode(po);
1899 if (wpath == NULL)
1900 return NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00001901
Victor Stinner8c62be82010-05-06 00:08:46 +00001902 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 res = wstatfunc(wpath, &st);
1904 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001905
Victor Stinner8c62be82010-05-06 00:08:46 +00001906 if (res != 0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001907 return win32_error_object("stat", po);
Victor Stinner4195b5c2012-02-08 23:03:19 +01001908 return _pystat_fromstructstat(&st);
Victor Stinner8c62be82010-05-06 00:08:46 +00001909 }
1910 /* Drop the argument parsing error as narrow strings
1911 are also valid. */
1912 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001913#endif
1914
Victor Stinner4195b5c2012-02-08 23:03:19 +01001915 if (!PyArg_ParseTuple(args, format,
1916 PyUnicode_FSConverter, &opath))
Victor Stinner8c62be82010-05-06 00:08:46 +00001917 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001918#ifdef MS_WINDOWS
1919 if (win32_warn_bytes_api()) {
1920 Py_DECREF(opath);
1921 return NULL;
1922 }
1923#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001924 path = PyBytes_AsString(opath);
1925 Py_BEGIN_ALLOW_THREADS
1926 res = (*statfunc)(path, &st);
1927 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001928
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001930#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001932#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001934#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 }
1936 else
Victor Stinner4195b5c2012-02-08 23:03:19 +01001937 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001938
Victor Stinner8c62be82010-05-06 00:08:46 +00001939 Py_DECREF(opath);
1940 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001941}
1942
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001943/* POSIX methods */
1944
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001945PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001946"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001947Use the real uid/gid to test for access to a path. Note that most\n\
1948operations will use the effective uid/gid, therefore this routine can\n\
1949be used in a suid/sgid environment to test if the invoking user has the\n\
1950specified access to the path. The mode argument can be F_OK to test\n\
1951existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001952
1953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001954posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001955{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001956 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001957 int mode;
1958
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001959#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001960 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02001961 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001963 wchar_t* wpath = PyUnicode_AsUnicode(po);
1964 if (wpath == NULL)
1965 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001967 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00001968 Py_END_ALLOW_THREADS
1969 goto finish;
1970 }
1971 /* Drop the argument parsing error as narrow strings
1972 are also valid. */
1973 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001974 if (!PyArg_ParseTuple(args, "yi:access", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00001975 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001976 if (win32_warn_bytes_api())
1977 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 Py_BEGIN_ALLOW_THREADS
1979 attr = GetFileAttributesA(path);
1980 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001981finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 if (attr == 0xFFFFFFFF)
1983 /* File does not exist, or cannot read attributes */
1984 return PyBool_FromLong(0);
1985 /* Access is possible if either write access wasn't requested, or
1986 the file isn't read-only, or if it's a directory, as there are
1987 no read-only directories on Windows. */
1988 return PyBool_FromLong(!(mode & 2)
1989 || !(attr & FILE_ATTRIBUTE_READONLY)
1990 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001991#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001992 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00001993 int res;
1994 if (!PyArg_ParseTuple(args, "O&i:access",
1995 PyUnicode_FSConverter, &opath, &mode))
1996 return NULL;
1997 path = PyBytes_AsString(opath);
1998 Py_BEGIN_ALLOW_THREADS
1999 res = access(path, mode);
2000 Py_END_ALLOW_THREADS
2001 Py_DECREF(opath);
2002 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002003#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002004}
2005
Guido van Rossumd371ff11999-01-25 16:12:23 +00002006#ifndef F_OK
2007#define F_OK 0
2008#endif
2009#ifndef R_OK
2010#define R_OK 4
2011#endif
2012#ifndef W_OK
2013#define W_OK 2
2014#endif
2015#ifndef X_OK
2016#define X_OK 1
2017#endif
2018
2019#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002020PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002021"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002022Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002023
2024static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002025posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002026{
Victor Stinner8c62be82010-05-06 00:08:46 +00002027 int id;
2028 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002029
Victor Stinner8c62be82010-05-06 00:08:46 +00002030 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2031 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002032
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002033#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 /* file descriptor 0 only, the default input device (stdin) */
2035 if (id == 0) {
2036 ret = ttyname();
2037 }
2038 else {
2039 ret = NULL;
2040 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002041#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002043#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002044 if (ret == NULL)
2045 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002046 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002047}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002048#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002049
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002050#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002051PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002052"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002053Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002054
2055static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002056posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002057{
Victor Stinner8c62be82010-05-06 00:08:46 +00002058 char *ret;
2059 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002060
Greg Wardb48bc172000-03-01 21:51:56 +00002061#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002062 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002063#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002064 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002065#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002066 if (ret == NULL)
2067 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002068 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002069}
2070#endif
2071
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002072PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002073"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002074Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002075
Barry Warsaw53699e91996-12-10 23:23:01 +00002076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002077posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002078{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002079#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002080 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002081#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002082 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00002083#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002085#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002087#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002088}
2089
Fred Drake4d1e64b2002-04-15 19:40:07 +00002090#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002091PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002092"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00002093Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002094opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002095
2096static PyObject *
2097posix_fchdir(PyObject *self, PyObject *fdobj)
2098{
Victor Stinner8c62be82010-05-06 00:08:46 +00002099 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002100}
2101#endif /* HAVE_FCHDIR */
2102
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002103
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002104PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002105"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002106Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002107
Barry Warsaw53699e91996-12-10 23:23:01 +00002108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002109posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002110{
Victor Stinner8c62be82010-05-06 00:08:46 +00002111 PyObject *opath = NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002112 const char *path = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 int i;
2114 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002115#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002116 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002117 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00002118 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002119 wchar_t *wpath = PyUnicode_AsUnicode(po);
2120 if (wpath == NULL)
2121 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002122 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02002123 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002124 if (attr != 0xFFFFFFFF) {
2125 if (i & _S_IWRITE)
2126 attr &= ~FILE_ATTRIBUTE_READONLY;
2127 else
2128 attr |= FILE_ATTRIBUTE_READONLY;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002129 res = SetFileAttributesW(wpath, attr);
Victor Stinner8c62be82010-05-06 00:08:46 +00002130 }
2131 else
2132 res = 0;
2133 Py_END_ALLOW_THREADS
2134 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02002135 return win32_error_object("chmod", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002136 Py_INCREF(Py_None);
2137 return Py_None;
2138 }
2139 /* Drop the argument parsing error as narrow strings
2140 are also valid. */
2141 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002142
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002143 if (!PyArg_ParseTuple(args, "yi:chmod", &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002144 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002145 if (win32_warn_bytes_api())
2146 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002147 Py_BEGIN_ALLOW_THREADS
2148 attr = GetFileAttributesA(path);
2149 if (attr != 0xFFFFFFFF) {
2150 if (i & _S_IWRITE)
2151 attr &= ~FILE_ATTRIBUTE_READONLY;
2152 else
2153 attr |= FILE_ATTRIBUTE_READONLY;
2154 res = SetFileAttributesA(path, attr);
2155 }
2156 else
2157 res = 0;
2158 Py_END_ALLOW_THREADS
2159 if (!res) {
2160 win32_error("chmod", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002161 return NULL;
2162 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002163 Py_INCREF(Py_None);
2164 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002165#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00002166 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2167 &opath, &i))
2168 return NULL;
2169 path = PyBytes_AsString(opath);
2170 Py_BEGIN_ALLOW_THREADS
2171 res = chmod(path, i);
2172 Py_END_ALLOW_THREADS
2173 if (res < 0)
2174 return posix_error_with_allocated_filename(opath);
2175 Py_DECREF(opath);
2176 Py_INCREF(Py_None);
2177 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002178#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002179}
2180
Christian Heimes4e30a842007-11-30 22:12:06 +00002181#ifdef HAVE_FCHMOD
2182PyDoc_STRVAR(posix_fchmod__doc__,
2183"fchmod(fd, mode)\n\n\
2184Change the access permissions of the file given by file\n\
2185descriptor fd.");
2186
2187static PyObject *
2188posix_fchmod(PyObject *self, PyObject *args)
2189{
Victor Stinner8c62be82010-05-06 00:08:46 +00002190 int fd, mode, res;
2191 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2192 return NULL;
2193 Py_BEGIN_ALLOW_THREADS
2194 res = fchmod(fd, mode);
2195 Py_END_ALLOW_THREADS
2196 if (res < 0)
2197 return posix_error();
2198 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002199}
2200#endif /* HAVE_FCHMOD */
2201
2202#ifdef HAVE_LCHMOD
2203PyDoc_STRVAR(posix_lchmod__doc__,
2204"lchmod(path, mode)\n\n\
2205Change the access permissions of a file. If path is a symlink, this\n\
2206affects the link itself rather than the target.");
2207
2208static PyObject *
2209posix_lchmod(PyObject *self, PyObject *args)
2210{
Victor Stinner8c62be82010-05-06 00:08:46 +00002211 PyObject *opath;
2212 char *path;
2213 int i;
2214 int res;
2215 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2216 &opath, &i))
2217 return NULL;
2218 path = PyBytes_AsString(opath);
2219 Py_BEGIN_ALLOW_THREADS
2220 res = lchmod(path, i);
2221 Py_END_ALLOW_THREADS
2222 if (res < 0)
2223 return posix_error_with_allocated_filename(opath);
2224 Py_DECREF(opath);
2225 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002226}
2227#endif /* HAVE_LCHMOD */
2228
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002229
Thomas Wouterscf297e42007-02-23 15:07:44 +00002230#ifdef HAVE_CHFLAGS
2231PyDoc_STRVAR(posix_chflags__doc__,
2232"chflags(path, flags)\n\n\
2233Set file flags.");
2234
2235static PyObject *
2236posix_chflags(PyObject *self, PyObject *args)
2237{
Victor Stinner8c62be82010-05-06 00:08:46 +00002238 PyObject *opath;
2239 char *path;
2240 unsigned long flags;
2241 int res;
2242 if (!PyArg_ParseTuple(args, "O&k:chflags",
2243 PyUnicode_FSConverter, &opath, &flags))
2244 return NULL;
2245 path = PyBytes_AsString(opath);
2246 Py_BEGIN_ALLOW_THREADS
2247 res = chflags(path, flags);
2248 Py_END_ALLOW_THREADS
2249 if (res < 0)
2250 return posix_error_with_allocated_filename(opath);
2251 Py_DECREF(opath);
2252 Py_INCREF(Py_None);
2253 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002254}
2255#endif /* HAVE_CHFLAGS */
2256
2257#ifdef HAVE_LCHFLAGS
2258PyDoc_STRVAR(posix_lchflags__doc__,
2259"lchflags(path, flags)\n\n\
2260Set file flags.\n\
2261This function will not follow symbolic links.");
2262
2263static PyObject *
2264posix_lchflags(PyObject *self, PyObject *args)
2265{
Victor Stinner8c62be82010-05-06 00:08:46 +00002266 PyObject *opath;
2267 char *path;
2268 unsigned long flags;
2269 int res;
2270 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2271 PyUnicode_FSConverter, &opath, &flags))
2272 return NULL;
2273 path = PyBytes_AsString(opath);
2274 Py_BEGIN_ALLOW_THREADS
2275 res = lchflags(path, flags);
2276 Py_END_ALLOW_THREADS
2277 if (res < 0)
2278 return posix_error_with_allocated_filename(opath);
2279 Py_DECREF(opath);
2280 Py_INCREF(Py_None);
2281 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002282}
2283#endif /* HAVE_LCHFLAGS */
2284
Martin v. Löwis244edc82001-10-04 22:44:26 +00002285#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002286PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002287"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002288Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002289
2290static PyObject *
2291posix_chroot(PyObject *self, PyObject *args)
2292{
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002294}
2295#endif
2296
Guido van Rossum21142a01999-01-08 21:05:37 +00002297#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002298PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002299"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002300force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002301
2302static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002303posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002304{
Stefan Krah0e803b32010-11-26 16:16:47 +00002305 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002306}
2307#endif /* HAVE_FSYNC */
2308
Ross Lagerwall7807c352011-03-17 20:20:30 +02002309#ifdef HAVE_SYNC
2310PyDoc_STRVAR(posix_sync__doc__,
2311"sync()\n\n\
2312Force write of everything to disk.");
2313
2314static PyObject *
2315posix_sync(PyObject *self, PyObject *noargs)
2316{
2317 Py_BEGIN_ALLOW_THREADS
2318 sync();
2319 Py_END_ALLOW_THREADS
2320 Py_RETURN_NONE;
2321}
2322#endif
2323
Guido van Rossum21142a01999-01-08 21:05:37 +00002324#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002325
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002326#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002327extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2328#endif
2329
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002330PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002331"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002332force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002333 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002334
2335static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002336posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002337{
Stefan Krah0e803b32010-11-26 16:16:47 +00002338 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002339}
2340#endif /* HAVE_FDATASYNC */
2341
2342
Fredrik Lundh10723342000-07-10 16:38:09 +00002343#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002344PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002345"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002346Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002347
Barry Warsaw53699e91996-12-10 23:23:01 +00002348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002349posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002350{
Victor Stinner8c62be82010-05-06 00:08:46 +00002351 PyObject *opath;
2352 char *path;
2353 long uid, gid;
2354 int res;
2355 if (!PyArg_ParseTuple(args, "O&ll:chown",
2356 PyUnicode_FSConverter, &opath,
2357 &uid, &gid))
2358 return NULL;
2359 path = PyBytes_AsString(opath);
2360 Py_BEGIN_ALLOW_THREADS
2361 res = chown(path, (uid_t) uid, (gid_t) gid);
2362 Py_END_ALLOW_THREADS
2363 if (res < 0)
2364 return posix_error_with_allocated_filename(opath);
2365 Py_DECREF(opath);
2366 Py_INCREF(Py_None);
2367 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002368}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002369#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002370
Christian Heimes4e30a842007-11-30 22:12:06 +00002371#ifdef HAVE_FCHOWN
2372PyDoc_STRVAR(posix_fchown__doc__,
2373"fchown(fd, uid, gid)\n\n\
2374Change the owner and group id of the file given by file descriptor\n\
2375fd to the numeric uid and gid.");
2376
2377static PyObject *
2378posix_fchown(PyObject *self, PyObject *args)
2379{
Victor Stinner8c62be82010-05-06 00:08:46 +00002380 int fd;
2381 long uid, gid;
2382 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002383 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002384 return NULL;
2385 Py_BEGIN_ALLOW_THREADS
2386 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2387 Py_END_ALLOW_THREADS
2388 if (res < 0)
2389 return posix_error();
2390 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002391}
2392#endif /* HAVE_FCHOWN */
2393
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002394#ifdef HAVE_LCHOWN
2395PyDoc_STRVAR(posix_lchown__doc__,
2396"lchown(path, uid, gid)\n\n\
2397Change the owner and group id of path to the numeric uid and gid.\n\
2398This function will not follow symbolic links.");
2399
2400static PyObject *
2401posix_lchown(PyObject *self, PyObject *args)
2402{
Victor Stinner8c62be82010-05-06 00:08:46 +00002403 PyObject *opath;
2404 char *path;
2405 long uid, gid;
2406 int res;
2407 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2408 PyUnicode_FSConverter, &opath,
2409 &uid, &gid))
2410 return NULL;
2411 path = PyBytes_AsString(opath);
2412 Py_BEGIN_ALLOW_THREADS
2413 res = lchown(path, (uid_t) uid, (gid_t) gid);
2414 Py_END_ALLOW_THREADS
2415 if (res < 0)
2416 return posix_error_with_allocated_filename(opath);
2417 Py_DECREF(opath);
2418 Py_INCREF(Py_None);
2419 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002420}
2421#endif /* HAVE_LCHOWN */
2422
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002423
Guido van Rossum36bc6801995-06-14 22:54:23 +00002424#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002425static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002426posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002427{
Victor Stinner8c62be82010-05-06 00:08:46 +00002428 char buf[1026];
2429 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002430
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002431#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002432 if (!use_bytes) {
2433 wchar_t wbuf[1026];
2434 wchar_t *wbuf2 = wbuf;
2435 PyObject *resobj;
2436 DWORD len;
2437 Py_BEGIN_ALLOW_THREADS
2438 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2439 /* If the buffer is large enough, len does not include the
2440 terminating \0. If the buffer is too small, len includes
2441 the space needed for the terminator. */
2442 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2443 wbuf2 = malloc(len * sizeof(wchar_t));
2444 if (wbuf2)
2445 len = GetCurrentDirectoryW(len, wbuf2);
2446 }
2447 Py_END_ALLOW_THREADS
2448 if (!wbuf2) {
2449 PyErr_NoMemory();
2450 return NULL;
2451 }
2452 if (!len) {
2453 if (wbuf2 != wbuf) free(wbuf2);
2454 return win32_error("getcwdu", NULL);
2455 }
2456 resobj = PyUnicode_FromWideChar(wbuf2, len);
2457 if (wbuf2 != wbuf) free(wbuf2);
2458 return resobj;
2459 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01002460
2461 if (win32_warn_bytes_api())
2462 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002463#endif
2464
Victor Stinner8c62be82010-05-06 00:08:46 +00002465 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002466#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002467 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002468#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002469 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002470#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002471 Py_END_ALLOW_THREADS
2472 if (res == NULL)
2473 return posix_error();
2474 if (use_bytes)
2475 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002476 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002477}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002478
2479PyDoc_STRVAR(posix_getcwd__doc__,
2480"getcwd() -> path\n\n\
2481Return a unicode string representing the current working directory.");
2482
2483static PyObject *
2484posix_getcwd_unicode(PyObject *self)
2485{
2486 return posix_getcwd(0);
2487}
2488
2489PyDoc_STRVAR(posix_getcwdb__doc__,
2490"getcwdb() -> path\n\n\
2491Return a bytes string representing the current working directory.");
2492
2493static PyObject *
2494posix_getcwd_bytes(PyObject *self)
2495{
2496 return posix_getcwd(1);
2497}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002498#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002500
Guido van Rossumb6775db1994-08-01 11:34:53 +00002501#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002502PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002503"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002504Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002505
Barry Warsaw53699e91996-12-10 23:23:01 +00002506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002507posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002508{
Victor Stinner8c62be82010-05-06 00:08:46 +00002509 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002510}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002511#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002512
Brian Curtin1b9df392010-11-24 20:24:31 +00002513#ifdef MS_WINDOWS
2514PyDoc_STRVAR(win32_link__doc__,
2515"link(src, dst)\n\n\
2516Create a hard link to a file.");
2517
2518static PyObject *
2519win32_link(PyObject *self, PyObject *args)
2520{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002521 PyObject *src, *dst;
2522 BOOL ok;
Brian Curtin1b9df392010-11-24 20:24:31 +00002523
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002524 if (PyArg_ParseTuple(args, "UU:link", &src, &dst))
Victor Stinnereb5657a2011-09-30 01:44:27 +02002525 {
2526 wchar_t *wsrc, *wdst;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002527
2528 wsrc = PyUnicode_AsUnicode(src);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002529 if (wsrc == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002530 goto error;
2531 wdst = PyUnicode_AsUnicode(dst);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002532 if (wdst == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002533 goto error;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002534
Brian Curtinfc889c42010-11-28 23:59:46 +00002535 Py_BEGIN_ALLOW_THREADS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002536 ok = CreateHardLinkW(wdst, wsrc, NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002537 Py_END_ALLOW_THREADS
2538
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002539 if (!ok)
Brian Curtinfc889c42010-11-28 23:59:46 +00002540 return win32_error("link", NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002541 Py_RETURN_NONE;
2542 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002543 else {
2544 PyErr_Clear();
2545 if (!PyArg_ParseTuple(args, "O&O&:link",
2546 PyUnicode_FSConverter, &src,
2547 PyUnicode_FSConverter, &dst))
2548 return NULL;
Brian Curtinfc889c42010-11-28 23:59:46 +00002549
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002550 if (win32_warn_bytes_api())
2551 goto error;
Brian Curtinfc889c42010-11-28 23:59:46 +00002552
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002553 Py_BEGIN_ALLOW_THREADS
2554 ok = CreateHardLinkA(PyBytes_AS_STRING(dst),
2555 PyBytes_AS_STRING(src),
2556 NULL);
2557 Py_END_ALLOW_THREADS
2558
2559 Py_XDECREF(src);
2560 Py_XDECREF(dst);
2561
2562 if (!ok)
2563 return win32_error("link", NULL);
2564 Py_RETURN_NONE;
2565
2566 error:
2567 Py_XDECREF(src);
2568 Py_XDECREF(dst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002569 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002570 }
Brian Curtin1b9df392010-11-24 20:24:31 +00002571}
2572#endif /* MS_WINDOWS */
2573
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002574
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002575PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002576"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002577Return a list containing the names of the entries in the directory.\n\
2578\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002579 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002580\n\
2581The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002582entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002583
Barry Warsaw53699e91996-12-10 23:23:01 +00002584static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002585posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002586{
Victor Stinner8c62be82010-05-06 00:08:46 +00002587 /* XXX Should redo this putting the (now four) versions of opendir
2588 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002589#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002590
Victor Stinner8c62be82010-05-06 00:08:46 +00002591 PyObject *d, *v;
2592 HANDLE hFindFile;
2593 BOOL result;
2594 WIN32_FIND_DATA FileData;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002595 const char *path;
2596 Py_ssize_t pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002597 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2598 char *bufptr = namebuf;
2599 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002600
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002601 PyObject *po = NULL;
2602 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002603 WIN32_FIND_DATAW wFileData;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002604 wchar_t *wnamebuf, *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002605
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002606 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002607 po_wchars = L".";
2608 len = 1;
2609 } else {
Victor Stinnerbeac78b2011-10-11 21:55:01 +02002610 po_wchars = PyUnicode_AsUnicodeAndSize(po, &len);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002611 if (po_wchars == NULL)
2612 return NULL;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002613 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002614 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002615 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2616 if (!wnamebuf) {
2617 PyErr_NoMemory();
2618 return NULL;
2619 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002620 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002621 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002622 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00002623 if (wch != L'/' && wch != L'\\' && wch != L':')
2624 wnamebuf[len++] = L'\\';
2625 wcscpy(wnamebuf + len, L"*.*");
2626 }
2627 if ((d = PyList_New(0)) == NULL) {
2628 free(wnamebuf);
2629 return NULL;
2630 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002631 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002632 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002633 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002634 if (hFindFile == INVALID_HANDLE_VALUE) {
2635 int error = GetLastError();
2636 if (error == ERROR_FILE_NOT_FOUND) {
2637 free(wnamebuf);
2638 return d;
2639 }
2640 Py_DECREF(d);
2641 win32_error_unicode("FindFirstFileW", wnamebuf);
2642 free(wnamebuf);
2643 return NULL;
2644 }
2645 do {
2646 /* Skip over . and .. */
2647 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2648 wcscmp(wFileData.cFileName, L"..") != 0) {
Victor Stinner9d3b93b2011-11-22 02:27:30 +01002649 v = PyUnicode_FromWideChar(wFileData.cFileName, wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00002650 if (v == NULL) {
2651 Py_DECREF(d);
2652 d = NULL;
2653 break;
2654 }
2655 if (PyList_Append(d, v) != 0) {
2656 Py_DECREF(v);
2657 Py_DECREF(d);
2658 d = NULL;
2659 break;
2660 }
2661 Py_DECREF(v);
2662 }
2663 Py_BEGIN_ALLOW_THREADS
2664 result = FindNextFileW(hFindFile, &wFileData);
2665 Py_END_ALLOW_THREADS
2666 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2667 it got to the end of the directory. */
2668 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2669 Py_DECREF(d);
2670 win32_error_unicode("FindNextFileW", wnamebuf);
2671 FindClose(hFindFile);
2672 free(wnamebuf);
2673 return NULL;
2674 }
2675 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002676
Victor Stinner8c62be82010-05-06 00:08:46 +00002677 if (FindClose(hFindFile) == FALSE) {
2678 Py_DECREF(d);
2679 win32_error_unicode("FindClose", wnamebuf);
2680 free(wnamebuf);
2681 return NULL;
2682 }
2683 free(wnamebuf);
2684 return d;
2685 }
2686 /* Drop the argument parsing error as narrow strings
2687 are also valid. */
2688 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002689
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002690 if (!PyArg_ParseTuple(args, "y#:listdir", &path, &pathlen))
Victor Stinner8c62be82010-05-06 00:08:46 +00002691 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002692 if (win32_warn_bytes_api())
2693 return NULL;
2694 if (pathlen+1 > MAX_PATH) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002695 PyErr_SetString(PyExc_ValueError, "path too long");
Victor Stinner8c62be82010-05-06 00:08:46 +00002696 return NULL;
2697 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002698 strcpy(namebuf, path);
2699 len = pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002700 if (len > 0) {
2701 char ch = namebuf[len-1];
2702 if (ch != SEP && ch != ALTSEP && ch != ':')
2703 namebuf[len++] = '/';
2704 strcpy(namebuf + len, "*.*");
2705 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002706
Victor Stinner8c62be82010-05-06 00:08:46 +00002707 if ((d = PyList_New(0)) == NULL)
2708 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002709
Antoine Pitroub73caab2010-08-09 23:39:31 +00002710 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002711 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002712 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002713 if (hFindFile == INVALID_HANDLE_VALUE) {
2714 int error = GetLastError();
2715 if (error == ERROR_FILE_NOT_FOUND)
2716 return d;
2717 Py_DECREF(d);
2718 return win32_error("FindFirstFile", namebuf);
2719 }
2720 do {
2721 /* Skip over . and .. */
2722 if (strcmp(FileData.cFileName, ".") != 0 &&
2723 strcmp(FileData.cFileName, "..") != 0) {
2724 v = PyBytes_FromString(FileData.cFileName);
2725 if (v == NULL) {
2726 Py_DECREF(d);
2727 d = NULL;
2728 break;
2729 }
2730 if (PyList_Append(d, v) != 0) {
2731 Py_DECREF(v);
2732 Py_DECREF(d);
2733 d = NULL;
2734 break;
2735 }
2736 Py_DECREF(v);
2737 }
2738 Py_BEGIN_ALLOW_THREADS
2739 result = FindNextFile(hFindFile, &FileData);
2740 Py_END_ALLOW_THREADS
2741 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2742 it got to the end of the directory. */
2743 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2744 Py_DECREF(d);
2745 win32_error("FindNextFile", namebuf);
2746 FindClose(hFindFile);
2747 return NULL;
2748 }
2749 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002750
Victor Stinner8c62be82010-05-06 00:08:46 +00002751 if (FindClose(hFindFile) == FALSE) {
2752 Py_DECREF(d);
2753 return win32_error("FindClose", namebuf);
2754 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002755
Victor Stinner8c62be82010-05-06 00:08:46 +00002756 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002757
Tim Peters0bb44a42000-09-15 07:44:49 +00002758#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002759
2760#ifndef MAX_PATH
2761#define MAX_PATH CCHMAXPATH
2762#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002763 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002764 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002765 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002766 PyObject *d, *v;
2767 char namebuf[MAX_PATH+5];
2768 HDIR hdir = 1;
2769 ULONG srchcnt = 1;
2770 FILEFINDBUF3 ep;
2771 APIRET rc;
2772
Victor Stinner8c62be82010-05-06 00:08:46 +00002773 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002774 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002775 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002776 name = PyBytes_AsString(oname);
2777 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002778 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002779 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002780 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002781 return NULL;
2782 }
2783 strcpy(namebuf, name);
2784 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002785 if (*pt == ALTSEP)
2786 *pt = SEP;
2787 if (namebuf[len-1] != SEP)
2788 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002789 strcpy(namebuf + len, "*.*");
2790
Neal Norwitz6c913782007-10-14 03:23:09 +00002791 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002792 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002793 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002794 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002795
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002796 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2797 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002798 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002799 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2800 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2801 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002802
2803 if (rc != NO_ERROR) {
2804 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002805 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002806 }
2807
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002808 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002809 do {
2810 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002811 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002812 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002813
2814 strcpy(namebuf, ep.achName);
2815
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002816 /* Leave Case of Name Alone -- In Native Form */
2817 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002818
Christian Heimes72b710a2008-05-26 13:28:38 +00002819 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002820 if (v == NULL) {
2821 Py_DECREF(d);
2822 d = NULL;
2823 break;
2824 }
2825 if (PyList_Append(d, v) != 0) {
2826 Py_DECREF(v);
2827 Py_DECREF(d);
2828 d = NULL;
2829 break;
2830 }
2831 Py_DECREF(v);
2832 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2833 }
2834
Victor Stinnerdcb24032010-04-22 12:08:36 +00002835 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002836 return d;
2837#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 PyObject *oname;
2839 char *name;
2840 PyObject *d, *v;
2841 DIR *dirp;
2842 struct dirent *ep;
2843 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002844
Victor Stinner8c62be82010-05-06 00:08:46 +00002845 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002846 /* v is never read, so it does not need to be initialized yet. */
2847 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002848 arg_is_unicode = 0;
2849 PyErr_Clear();
2850 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002851 oname = NULL;
2852 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002853 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002854 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002855 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002856 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002858 Py_BEGIN_ALLOW_THREADS
2859 dirp = opendir(name);
2860 Py_END_ALLOW_THREADS
2861 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002862 return posix_error_with_allocated_filename(oname);
2863 }
2864 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002865 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002866 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002867 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002868 Py_DECREF(oname);
2869 return NULL;
2870 }
2871 for (;;) {
2872 errno = 0;
2873 Py_BEGIN_ALLOW_THREADS
2874 ep = readdir(dirp);
2875 Py_END_ALLOW_THREADS
2876 if (ep == NULL) {
2877 if (errno == 0) {
2878 break;
2879 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002880 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002881 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002882 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002883 Py_DECREF(d);
2884 return posix_error_with_allocated_filename(oname);
2885 }
2886 }
2887 if (ep->d_name[0] == '.' &&
2888 (NAMLEN(ep) == 1 ||
2889 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2890 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002891 if (arg_is_unicode)
2892 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2893 else
2894 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002895 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002896 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002897 break;
2898 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 if (PyList_Append(d, v) != 0) {
2900 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002901 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002902 break;
2903 }
2904 Py_DECREF(v);
2905 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002906 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002907 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002908 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002909 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002910
Victor Stinner8c62be82010-05-06 00:08:46 +00002911 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002912
Tim Peters0bb44a42000-09-15 07:44:49 +00002913#endif /* which OS */
2914} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002915
Antoine Pitrou8250e232011-02-25 23:41:16 +00002916#ifdef HAVE_FDOPENDIR
Charles-François Natali77940902012-02-06 19:54:48 +01002917PyDoc_STRVAR(posix_flistdir__doc__,
2918"flistdir(fd) -> list_of_strings\n\n\
Charles-François Natali76961fa2012-01-10 20:25:09 +01002919Like listdir(), but uses a file descriptor instead.");
Antoine Pitrou8250e232011-02-25 23:41:16 +00002920
2921static PyObject *
Charles-François Natali77940902012-02-06 19:54:48 +01002922posix_flistdir(PyObject *self, PyObject *args)
Antoine Pitrou8250e232011-02-25 23:41:16 +00002923{
2924 PyObject *d, *v;
2925 DIR *dirp;
2926 struct dirent *ep;
2927 int fd;
2928
2929 errno = 0;
Charles-François Natali77940902012-02-06 19:54:48 +01002930 if (!PyArg_ParseTuple(args, "i:flistdir", &fd))
Antoine Pitrou8250e232011-02-25 23:41:16 +00002931 return NULL;
Charles-François Natali76961fa2012-01-10 20:25:09 +01002932 /* closedir() closes the FD, so we duplicate it */
2933 fd = dup(fd);
2934 if (fd < 0)
2935 return posix_error();
Antoine Pitrou8250e232011-02-25 23:41:16 +00002936 Py_BEGIN_ALLOW_THREADS
2937 dirp = fdopendir(fd);
2938 Py_END_ALLOW_THREADS
2939 if (dirp == NULL) {
2940 close(fd);
2941 return posix_error();
2942 }
2943 if ((d = PyList_New(0)) == NULL) {
2944 Py_BEGIN_ALLOW_THREADS
2945 closedir(dirp);
2946 Py_END_ALLOW_THREADS
2947 return NULL;
2948 }
2949 for (;;) {
2950 errno = 0;
2951 Py_BEGIN_ALLOW_THREADS
2952 ep = readdir(dirp);
2953 Py_END_ALLOW_THREADS
2954 if (ep == NULL) {
2955 if (errno == 0) {
2956 break;
2957 } else {
2958 Py_BEGIN_ALLOW_THREADS
Charles-François Natalif2840a82012-01-08 20:30:47 +01002959 rewinddir(dirp);
Antoine Pitrou8250e232011-02-25 23:41:16 +00002960 closedir(dirp);
2961 Py_END_ALLOW_THREADS
2962 Py_DECREF(d);
2963 return posix_error();
2964 }
2965 }
2966 if (ep->d_name[0] == '.' &&
2967 (NAMLEN(ep) == 1 ||
2968 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2969 continue;
2970 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2971 if (v == NULL) {
2972 Py_CLEAR(d);
2973 break;
2974 }
2975 if (PyList_Append(d, v) != 0) {
2976 Py_DECREF(v);
2977 Py_CLEAR(d);
2978 break;
2979 }
2980 Py_DECREF(v);
2981 }
2982 Py_BEGIN_ALLOW_THREADS
Charles-François Natalif2840a82012-01-08 20:30:47 +01002983 rewinddir(dirp);
Antoine Pitrou8250e232011-02-25 23:41:16 +00002984 closedir(dirp);
2985 Py_END_ALLOW_THREADS
2986
2987 return d;
2988}
2989#endif
2990
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002991#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002992/* A helper function for abspath on win32 */
2993static PyObject *
2994posix__getfullpathname(PyObject *self, PyObject *args)
2995{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002996 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002997 char outbuf[MAX_PATH*2];
2998 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002999 PyObject *po;
3000
3001 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3002 {
3003 wchar_t *wpath;
3004 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3005 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003006 DWORD result;
3007 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003008
3009 wpath = PyUnicode_AsUnicode(po);
3010 if (wpath == NULL)
3011 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003012 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003013 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003014 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003015 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003016 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003017 if (!woutbufp)
3018 return PyErr_NoMemory();
3019 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3020 }
3021 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003022 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003023 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003024 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003025 if (woutbufp != woutbuf)
3026 free(woutbufp);
3027 return v;
3028 }
3029 /* Drop the argument parsing error as narrow strings
3030 are also valid. */
3031 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003032
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003033 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3034 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003035 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003036 if (win32_warn_bytes_api())
3037 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003038 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003039 outbuf, &temp)) {
3040 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003041 return NULL;
3042 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003043 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3044 return PyUnicode_Decode(outbuf, strlen(outbuf),
3045 Py_FileSystemDefaultEncoding, NULL);
3046 }
3047 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003048} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003049
Brian Curtind25aef52011-06-13 15:16:04 -05003050
Brian Curtinf5e76d02010-11-24 13:14:05 +00003051
Brian Curtind40e6f72010-07-08 21:39:08 +00003052/* A helper function for samepath on windows */
3053static PyObject *
3054posix__getfinalpathname(PyObject *self, PyObject *args)
3055{
3056 HANDLE hFile;
3057 int buf_size;
3058 wchar_t *target_path;
3059 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003060 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003061 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003062
Victor Stinnereb5657a2011-09-30 01:44:27 +02003063 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003064 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003065 path = PyUnicode_AsUnicode(po);
3066 if (path == NULL)
3067 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003068
3069 if(!check_GetFinalPathNameByHandle()) {
3070 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3071 NotImplementedError. */
3072 return PyErr_Format(PyExc_NotImplementedError,
3073 "GetFinalPathNameByHandle not available on this platform");
3074 }
3075
3076 hFile = CreateFileW(
3077 path,
3078 0, /* desired access */
3079 0, /* share mode */
3080 NULL, /* security attributes */
3081 OPEN_EXISTING,
3082 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3083 FILE_FLAG_BACKUP_SEMANTICS,
3084 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003085
Victor Stinnereb5657a2011-09-30 01:44:27 +02003086 if(hFile == INVALID_HANDLE_VALUE)
3087 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003088
3089 /* We have a good handle to the target, use it to determine the
3090 target path name. */
3091 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3092
3093 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003094 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003095
3096 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3097 if(!target_path)
3098 return PyErr_NoMemory();
3099
3100 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3101 buf_size, VOLUME_NAME_DOS);
3102 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003103 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003104
3105 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003106 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003107
3108 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003109 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003110 free(target_path);
3111 return result;
3112
3113} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003114
3115static PyObject *
3116posix__getfileinformation(PyObject *self, PyObject *args)
3117{
3118 HANDLE hFile;
3119 BY_HANDLE_FILE_INFORMATION info;
3120 int fd;
3121
3122 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3123 return NULL;
3124
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003125 if (!_PyVerify_fd(fd))
3126 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003127
3128 hFile = (HANDLE)_get_osfhandle(fd);
3129 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003130 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003131
3132 if (!GetFileInformationByHandle(hFile, &info))
3133 return win32_error("_getfileinformation", NULL);
3134
3135 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3136 info.nFileIndexHigh,
3137 info.nFileIndexLow);
3138}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003139
Brian Curtin95d028f2011-06-09 09:10:38 -05003140PyDoc_STRVAR(posix__isdir__doc__,
3141"Return true if the pathname refers to an existing directory.");
3142
Brian Curtin9c669cc2011-06-08 18:17:18 -05003143static PyObject *
3144posix__isdir(PyObject *self, PyObject *args)
3145{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003146 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003147 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003148 DWORD attributes;
3149
3150 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003151 wchar_t *wpath = PyUnicode_AsUnicode(po);
3152 if (wpath == NULL)
3153 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003154
3155 attributes = GetFileAttributesW(wpath);
3156 if (attributes == INVALID_FILE_ATTRIBUTES)
3157 Py_RETURN_FALSE;
3158 goto check;
3159 }
3160 /* Drop the argument parsing error as narrow strings
3161 are also valid. */
3162 PyErr_Clear();
3163
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003164 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003165 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003166 if (win32_warn_bytes_api())
3167 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003168 attributes = GetFileAttributesA(path);
3169 if (attributes == INVALID_FILE_ATTRIBUTES)
3170 Py_RETURN_FALSE;
3171
3172check:
3173 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3174 Py_RETURN_TRUE;
3175 else
3176 Py_RETURN_FALSE;
3177}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003178#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003179
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003180PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003181"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003182Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003183
Barry Warsaw53699e91996-12-10 23:23:01 +00003184static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003185posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003186{
Victor Stinner8c62be82010-05-06 00:08:46 +00003187 int res;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003188 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003189 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003190
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003191#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003192 PyObject *po;
3193 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode))
3194 {
3195 wchar_t *wpath = PyUnicode_AsUnicode(po);
3196 if (wpath == NULL)
3197 return NULL;
3198
Victor Stinner8c62be82010-05-06 00:08:46 +00003199 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003200 res = CreateDirectoryW(wpath, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003201 Py_END_ALLOW_THREADS
3202 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003203 return win32_error_object("mkdir", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003204 Py_INCREF(Py_None);
3205 return Py_None;
3206 }
3207 /* Drop the argument parsing error as narrow strings
3208 are also valid. */
3209 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003210 if (!PyArg_ParseTuple(args, "y|i:mkdir", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003212 if (win32_warn_bytes_api())
3213 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003214 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003215 res = CreateDirectoryA(path, NULL);
3216 Py_END_ALLOW_THREADS
3217 if (!res) {
3218 win32_error("mkdir", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 return NULL;
3220 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003221 Py_INCREF(Py_None);
3222 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003223#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003224 PyObject *opath;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003225
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
3227 PyUnicode_FSConverter, &opath, &mode))
3228 return NULL;
3229 path = PyBytes_AsString(opath);
3230 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00003231#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003233#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003234 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003235#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 Py_END_ALLOW_THREADS
3237 if (res < 0)
3238 return posix_error_with_allocated_filename(opath);
3239 Py_DECREF(opath);
3240 Py_INCREF(Py_None);
3241 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003242#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003243}
3244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003245
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003246/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3247#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003248#include <sys/resource.h>
3249#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003250
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003251
3252#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003253PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003254"nice(inc) -> new_priority\n\n\
3255Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003256
Barry Warsaw53699e91996-12-10 23:23:01 +00003257static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003258posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003259{
Victor Stinner8c62be82010-05-06 00:08:46 +00003260 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003261
Victor Stinner8c62be82010-05-06 00:08:46 +00003262 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3263 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003264
Victor Stinner8c62be82010-05-06 00:08:46 +00003265 /* There are two flavours of 'nice': one that returns the new
3266 priority (as required by almost all standards out there) and the
3267 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3268 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003269
Victor Stinner8c62be82010-05-06 00:08:46 +00003270 If we are of the nice family that returns the new priority, we
3271 need to clear errno before the call, and check if errno is filled
3272 before calling posix_error() on a returnvalue of -1, because the
3273 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003274
Victor Stinner8c62be82010-05-06 00:08:46 +00003275 errno = 0;
3276 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003277#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003278 if (value == 0)
3279 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003280#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 if (value == -1 && errno != 0)
3282 /* either nice() or getpriority() returned an error */
3283 return posix_error();
3284 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003285}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003286#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003287
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003288
3289#ifdef HAVE_GETPRIORITY
3290PyDoc_STRVAR(posix_getpriority__doc__,
3291"getpriority(which, who) -> current_priority\n\n\
3292Get program scheduling priority.");
3293
3294static PyObject *
3295posix_getpriority(PyObject *self, PyObject *args)
3296{
3297 int which, who, retval;
3298
3299 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3300 return NULL;
3301 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003302 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003303 if (errno != 0)
3304 return posix_error();
3305 return PyLong_FromLong((long)retval);
3306}
3307#endif /* HAVE_GETPRIORITY */
3308
3309
3310#ifdef HAVE_SETPRIORITY
3311PyDoc_STRVAR(posix_setpriority__doc__,
3312"setpriority(which, who, prio) -> None\n\n\
3313Set program scheduling priority.");
3314
3315static PyObject *
3316posix_setpriority(PyObject *self, PyObject *args)
3317{
3318 int which, who, prio, retval;
3319
3320 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3321 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003322 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003323 if (retval == -1)
3324 return posix_error();
3325 Py_RETURN_NONE;
3326}
3327#endif /* HAVE_SETPRIORITY */
3328
3329
Barry Warsaw53699e91996-12-10 23:23:01 +00003330static PyObject *
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003331internal_rename(PyObject *self, PyObject *args, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003332{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003333#ifdef MS_WINDOWS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003334 PyObject *src, *dst;
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003336 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
3337 if (PyArg_ParseTuple(args,
3338 is_replace ? "UU:replace" : "UU:rename",
3339 &src, &dst))
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003340 {
3341 wchar_t *wsrc, *wdst;
3342
3343 wsrc = PyUnicode_AsUnicode(src);
3344 if (wsrc == NULL)
3345 return NULL;
3346 wdst = PyUnicode_AsUnicode(dst);
3347 if (wdst == NULL)
3348 return NULL;
3349 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003350 result = MoveFileExW(wsrc, wdst, flags);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003351 Py_END_ALLOW_THREADS
3352 if (!result)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003353 return win32_error(is_replace ? "replace" : "rename", NULL);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003354 Py_INCREF(Py_None);
3355 return Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003357 else {
3358 PyErr_Clear();
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003359 if (!PyArg_ParseTuple(args,
3360 is_replace ? "O&O&:replace" : "O&O&:rename",
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003361 PyUnicode_FSConverter, &src,
3362 PyUnicode_FSConverter, &dst))
3363 return NULL;
3364
3365 if (win32_warn_bytes_api())
3366 goto error;
3367
3368 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003369 result = MoveFileExA(PyBytes_AS_STRING(src),
3370 PyBytes_AS_STRING(dst), flags);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003371 Py_END_ALLOW_THREADS
3372
3373 Py_XDECREF(src);
3374 Py_XDECREF(dst);
3375
3376 if (!result)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003377 return win32_error(is_replace ? "replace" : "rename", NULL);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003378 Py_INCREF(Py_None);
3379 return Py_None;
3380
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003381error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003382 Py_XDECREF(src);
3383 Py_XDECREF(dst);
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003385 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003386#else
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003387 return posix_2str(args,
3388 is_replace ? "O&O&:replace" : "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003389#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003390}
3391
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003392PyDoc_STRVAR(posix_rename__doc__,
3393"rename(old, new)\n\n\
3394Rename a file or directory.");
3395
3396static PyObject *
3397posix_rename(PyObject *self, PyObject *args)
3398{
3399 return internal_rename(self, args, 0);
3400}
3401
3402PyDoc_STRVAR(posix_replace__doc__,
3403"replace(old, new)\n\n\
3404Rename a file or directory, overwriting the destination.");
3405
3406static PyObject *
3407posix_replace(PyObject *self, PyObject *args)
3408{
3409 return internal_rename(self, args, 1);
3410}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003411
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003412PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003413"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003414Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003415
Barry Warsaw53699e91996-12-10 23:23:01 +00003416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003417posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003418{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003419#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003420 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003421#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003422 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003423#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003424}
3425
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003426
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003427PyDoc_STRVAR(posix_stat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01003428"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003429Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003430
Barry Warsaw53699e91996-12-10 23:23:01 +00003431static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01003432posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003433{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003434#ifdef MS_WINDOWS
Victor Stinner4195b5c2012-02-08 23:03:19 +01003435 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003436#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01003437 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003438#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003439}
3440
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003441
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003442#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003443PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003444"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003445Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003446
Barry Warsaw53699e91996-12-10 23:23:01 +00003447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003448posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003449{
Victor Stinner8c62be82010-05-06 00:08:46 +00003450 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003451#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003452 wchar_t *command;
3453 if (!PyArg_ParseTuple(args, "u:system", &command))
3454 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003455
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 Py_BEGIN_ALLOW_THREADS
3457 sts = _wsystem(command);
3458 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003459#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 PyObject *command_obj;
3461 char *command;
3462 if (!PyArg_ParseTuple(args, "O&:system",
3463 PyUnicode_FSConverter, &command_obj))
3464 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003465
Victor Stinner8c62be82010-05-06 00:08:46 +00003466 command = PyBytes_AsString(command_obj);
3467 Py_BEGIN_ALLOW_THREADS
3468 sts = system(command);
3469 Py_END_ALLOW_THREADS
3470 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003471#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003472 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003473}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003474#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003475
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003476
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003477PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003478"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003479Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003480
Barry Warsaw53699e91996-12-10 23:23:01 +00003481static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003482posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003483{
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 int i;
3485 if (!PyArg_ParseTuple(args, "i:umask", &i))
3486 return NULL;
3487 i = (int)umask(i);
3488 if (i < 0)
3489 return posix_error();
3490 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003491}
3492
Brian Curtind40e6f72010-07-08 21:39:08 +00003493#ifdef MS_WINDOWS
3494
3495/* override the default DeleteFileW behavior so that directory
3496symlinks can be removed with this function, the same as with
3497Unix symlinks */
3498BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3499{
3500 WIN32_FILE_ATTRIBUTE_DATA info;
3501 WIN32_FIND_DATAW find_data;
3502 HANDLE find_data_handle;
3503 int is_directory = 0;
3504 int is_link = 0;
3505
3506 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3507 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003508
Brian Curtind40e6f72010-07-08 21:39:08 +00003509 /* Get WIN32_FIND_DATA structure for the path to determine if
3510 it is a symlink */
3511 if(is_directory &&
3512 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3513 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3514
3515 if(find_data_handle != INVALID_HANDLE_VALUE) {
3516 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3517 FindClose(find_data_handle);
3518 }
3519 }
3520 }
3521
3522 if (is_directory && is_link)
3523 return RemoveDirectoryW(lpFileName);
3524
3525 return DeleteFileW(lpFileName);
3526}
3527#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003529PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003530"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003531Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003532
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003533PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003534"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003535Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003536
Barry Warsaw53699e91996-12-10 23:23:01 +00003537static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003538posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003539{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003540#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003541 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3542 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003543#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003545#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003546}
3547
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003548
Guido van Rossumb6775db1994-08-01 11:34:53 +00003549#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003550PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003551"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003552Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003553
Barry Warsaw53699e91996-12-10 23:23:01 +00003554static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003555posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003556{
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 struct utsname u;
3558 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003559
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 Py_BEGIN_ALLOW_THREADS
3561 res = uname(&u);
3562 Py_END_ALLOW_THREADS
3563 if (res < 0)
3564 return posix_error();
3565 return Py_BuildValue("(sssss)",
3566 u.sysname,
3567 u.nodename,
3568 u.release,
3569 u.version,
3570 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003571}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003572#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003573
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003574
Larry Hastings76ad59b2012-05-03 00:30:07 -07003575static int
3576split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
3577{
3578 int result = 0;
Benjamin Peterson3e2e3682012-05-04 01:14:03 -04003579 PyObject *divmod = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003580 divmod = PyNumber_Divmod(py_long, billion);
3581 if (!divmod)
3582 goto exit;
3583 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
3584 if ((*s == -1) && PyErr_Occurred())
3585 goto exit;
3586 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04003587 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07003588 goto exit;
3589
3590 result = 1;
3591exit:
3592 Py_XDECREF(divmod);
3593 return result;
3594}
3595
3596
3597typedef int (*parameter_converter_t)(PyObject *, void *);
3598
3599typedef struct {
3600 /* input only */
3601 char path_format;
3602 parameter_converter_t converter;
3603 char *function_name;
3604 char *first_argument_name;
3605 PyObject *args;
3606 PyObject *kwargs;
3607
3608 /* input/output */
3609 PyObject **path;
3610
3611 /* output only */
3612 int now;
3613 time_t atime_s;
3614 long atime_ns;
3615 time_t mtime_s;
3616 long mtime_ns;
3617} utime_arguments;
3618
3619#define DECLARE_UA(ua, fname) \
3620 utime_arguments ua; \
3621 memset(&ua, 0, sizeof(ua)); \
3622 ua.function_name = fname; \
3623 ua.args = args; \
3624 ua.kwargs = kwargs; \
3625 ua.first_argument_name = "path"; \
3626
3627/* UA_TO_FILETIME doesn't declare atime and mtime for you */
3628#define UA_TO_FILETIME(ua, atime, mtime) \
3629 time_t_to_FILE_TIME(ua.atime_s, ua.atime_ns, &atime); \
3630 time_t_to_FILE_TIME(ua.mtime_s, ua.mtime_ns, &mtime)
3631
3632/* the rest of these macros declare the output variable for you */
3633#define UA_TO_TIMESPEC(ua, ts) \
3634 struct timespec ts[2]; \
3635 ts[0].tv_sec = ua.atime_s; \
3636 ts[0].tv_nsec = ua.atime_ns; \
3637 ts[1].tv_sec = ua.mtime_s; \
3638 ts[1].tv_nsec = ua.mtime_ns
3639
3640#define UA_TO_TIMEVAL(ua, tv) \
3641 struct timeval tv[2]; \
3642 tv[0].tv_sec = ua.atime_s; \
3643 tv[0].tv_usec = ua.atime_ns / 1000; \
3644 tv[1].tv_sec = ua.mtime_s; \
3645 tv[1].tv_usec = ua.mtime_ns / 1000
3646
3647#define UA_TO_UTIMBUF(ua, u) \
3648 struct utimbuf u; \
3649 utimbuf.actime = ua.atime_s; \
3650 utimbuf.modtime = ua.mtime_s
3651
3652#define UA_TO_TIME_T(ua, timet) \
3653 time_t timet[2]; \
3654 timet[0] = ua.atime_s; \
3655 timet[1] = ua.mtime_s
3656
3657
3658/*
3659 * utime_read_time_arguments() processes arguments for the utime
3660 * family of functions.
Larry Hastings76ad59b2012-05-03 00:30:07 -07003661 */
Larry Hastingsb3336402012-05-04 02:31:57 -07003662
3663typedef enum {
3664 utime_success = 0,
3665 utime_parse_failure = 1,
3666 utime_times_and_ns_collision = 2,
3667 utime_times_conversion_failure = 3,
3668 utime_ns_conversion_failure = 4,
3669} utime_status;
3670
3671static utime_status
Larry Hastings76ad59b2012-05-03 00:30:07 -07003672utime_read_time_arguments(utime_arguments *ua)
3673{
3674 PyObject *times = NULL;
3675 PyObject *ns = NULL;
3676 char format[24];
3677 char *kwlist[4];
3678 char **kw = kwlist;
Larry Hastingsb3336402012-05-04 02:31:57 -07003679 utime_status return_value;
3680 int parse_result;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003681
3682 *kw++ = ua->first_argument_name;
3683 *kw++ = "times";
3684 *kw++ = "ns";
3685 *kw = NULL;
3686
3687 sprintf(format, "%c%s|O$O:%s",
3688 ua->path_format,
3689 ua->converter ? "&" : "",
3690 ua->function_name);
3691
3692 if (ua->converter)
Larry Hastingsb3336402012-05-04 02:31:57 -07003693 parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
Larry Hastings76ad59b2012-05-03 00:30:07 -07003694 format, kwlist, ua->converter, ua->path, &times, &ns);
3695 else
Larry Hastingsb3336402012-05-04 02:31:57 -07003696 parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs,
Larry Hastings76ad59b2012-05-03 00:30:07 -07003697 format, kwlist, ua->path, &times, &ns);
3698
Larry Hastingsb3336402012-05-04 02:31:57 -07003699 if (!parse_result)
3700 return utime_parse_failure;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003701
3702 if (times && ns) {
3703 PyErr_Format(PyExc_RuntimeError,
3704 "%s: you may specify either 'times'"
3705 " or 'ns' but not both",
3706 ua->function_name);
Larry Hastingsb3336402012-05-04 02:31:57 -07003707 return_value = utime_times_and_ns_collision;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003708 goto fail;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003709 }
3710
3711 if (times && (times != Py_None)) {
3712 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
3713 PyErr_Format(PyExc_TypeError,
3714 "%s: 'time' must be either"
Benjamin Peterson9bd9d742012-05-04 01:42:41 -04003715 " a tuple of two ints or None",
Larry Hastings76ad59b2012-05-03 00:30:07 -07003716 ua->function_name);
Larry Hastingsb3336402012-05-04 02:31:57 -07003717 return_value = utime_times_conversion_failure;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003718 goto fail;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003719 }
3720 ua->now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003721 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
3722 &ua->atime_s, &ua->atime_ns) == -1 ||
3723 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastingsb3336402012-05-04 02:31:57 -07003724 &ua->mtime_s, &ua->mtime_ns) == -1) {
3725 return_value = utime_times_conversion_failure;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003726 goto fail;
Larry Hastingsb3336402012-05-04 02:31:57 -07003727 }
3728 return utime_success;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003729 }
3730
3731 if (ns) {
3732 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
3733 PyErr_Format(PyExc_TypeError,
Benjamin Peterson9bd9d742012-05-04 01:42:41 -04003734 "%s: 'ns' must be a tuple of two ints",
Larry Hastings76ad59b2012-05-03 00:30:07 -07003735 ua->function_name);
Larry Hastingsb3336402012-05-04 02:31:57 -07003736 return_value = utime_ns_conversion_failure;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003737 goto fail;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003738 }
3739 ua->now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003740 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
3741 &ua->atime_s, &ua->atime_ns) ||
3742 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastingsb3336402012-05-04 02:31:57 -07003743 &ua->mtime_s, &ua->mtime_ns)) {
3744 return_value = utime_ns_conversion_failure;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003745 goto fail;
Larry Hastingsb3336402012-05-04 02:31:57 -07003746 }
3747 return utime_success;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003748 }
3749
3750 /* either times=None, or neither times nor ns was specified. use "now". */
3751 ua->now = 1;
Larry Hastingsb3336402012-05-04 02:31:57 -07003752 return utime_success;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04003753
3754 fail:
3755 if (ua->converter)
Richard Oudkerkf072b452012-05-04 12:01:31 +01003756 Py_DECREF(*ua->path);
Larry Hastingsb3336402012-05-04 02:31:57 -07003757 return return_value;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003758}
3759
3760
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003761PyDoc_STRVAR(posix_utime__doc__,
Larry Hastings76ad59b2012-05-03 00:30:07 -07003762"utime(path[, times=(atime, mtime), *, ns=(atime_ns, mtime_ns)])\n\
3763Set the access and modified time of the file.\n\
3764If the second argument ('times') is specified,\n\
3765 the values should be expressed as float seconds since the epoch.\n\
3766If the keyword argument 'ns' is specified,\n\
3767 the values should be expressed as integer nanoseconds since the epoch.\n\
3768If neither the second nor the 'ns' argument is specified,\n\
3769 utime uses the current time.\n\
3770Specifying both 'times' and 'ns' is an error.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003771
Barry Warsaw53699e91996-12-10 23:23:01 +00003772static PyObject *
Larry Hastings76ad59b2012-05-03 00:30:07 -07003773posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003774{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003775#ifdef MS_WINDOWS
Larry Hastings76ad59b2012-05-03 00:30:07 -07003776 PyObject *upath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003777 HANDLE hFile;
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 PyObject *result = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07003779 FILETIME atime, mtime;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003780
Larry Hastings76ad59b2012-05-03 00:30:07 -07003781 DECLARE_UA(ua, "utime");
3782
3783 ua.path_format = 'U';
3784 ua.path = &upath;
3785
Larry Hastingsb3336402012-05-04 02:31:57 -07003786 switch (utime_read_time_arguments(&ua)) {
3787 default:
3788 return NULL;
3789 case utime_success: {
Larry Hastings76ad59b2012-05-03 00:30:07 -07003790 wchar_t *wpath = PyUnicode_AsUnicode(upath);
Victor Stinnereb5657a2011-09-30 01:44:27 +02003791 if (wpath == NULL)
3792 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003793 Py_BEGIN_ALLOW_THREADS
3794 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3795 NULL, OPEN_EXISTING,
3796 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3797 Py_END_ALLOW_THREADS
3798 if (hFile == INVALID_HANDLE_VALUE)
Larry Hastings76ad59b2012-05-03 00:30:07 -07003799 return win32_error_object("utime", upath);
Larry Hastingsb3336402012-05-04 02:31:57 -07003800 break;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003801 }
Larry Hastingsb3336402012-05-04 02:31:57 -07003802 case utime_parse_failure: {
Larry Hastings76ad59b2012-05-03 00:30:07 -07003803 const char *apath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003804 /* Drop the argument parsing error as narrow strings
3805 are also valid. */
3806 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003807
Larry Hastings76ad59b2012-05-03 00:30:07 -07003808 ua.path_format = 'y';
3809 ua.path = (PyObject **)&apath;
Larry Hastingsb3336402012-05-04 02:31:57 -07003810 if (utime_read_time_arguments(&ua) != utime_success)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003811 return NULL;
3812 if (win32_warn_bytes_api())
Victor Stinner8c62be82010-05-06 00:08:46 +00003813 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003814
Victor Stinner8c62be82010-05-06 00:08:46 +00003815 Py_BEGIN_ALLOW_THREADS
3816 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3817 NULL, OPEN_EXISTING,
3818 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3819 Py_END_ALLOW_THREADS
3820 if (hFile == INVALID_HANDLE_VALUE) {
3821 win32_error("utime", apath);
Victor Stinner8c62be82010-05-06 00:08:46 +00003822 return NULL;
3823 }
Larry Hastingsb3336402012-05-04 02:31:57 -07003824 break;
3825 }
3826
Victor Stinner8c62be82010-05-06 00:08:46 +00003827 }
3828
Larry Hastings76ad59b2012-05-03 00:30:07 -07003829 if (ua.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003830 SYSTEMTIME now;
3831 GetSystemTime(&now);
3832 if (!SystemTimeToFileTime(&now, &mtime) ||
3833 !SystemTimeToFileTime(&now, &atime)) {
3834 win32_error("utime", NULL);
3835 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003836 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003837 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003838 else {
Larry Hastings76ad59b2012-05-03 00:30:07 -07003839 UA_TO_FILETIME(ua, atime, mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 }
3841 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3842 /* Avoid putting the file name into the error here,
3843 as that may confuse the user into believing that
3844 something is wrong with the file, when it also
3845 could be the time stamp that gives a problem. */
3846 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003847 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003848 }
3849 Py_INCREF(Py_None);
3850 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003851done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003852 CloseHandle(hFile);
3853 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003854#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00003855 PyObject *opath;
3856 char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003857 int res;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003858
Larry Hastings76ad59b2012-05-03 00:30:07 -07003859 DECLARE_UA(ua, "utime");
3860
3861 ua.path_format = 'O';
3862 ua.path = &opath;
3863 ua.converter = PyUnicode_FSConverter;
3864
Larry Hastingsb3336402012-05-04 02:31:57 -07003865 if (utime_read_time_arguments(&ua) != utime_success)
Victor Stinner8c62be82010-05-06 00:08:46 +00003866 return NULL;
3867 path = PyBytes_AsString(opath);
Larry Hastings76ad59b2012-05-03 00:30:07 -07003868 if (ua.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003869 Py_BEGIN_ALLOW_THREADS
3870 res = utime(path, NULL);
3871 Py_END_ALLOW_THREADS
3872 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003873 else {
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003874 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003875#ifdef HAVE_UTIMENSAT
Larry Hastings76ad59b2012-05-03 00:30:07 -07003876 UA_TO_TIMESPEC(ua, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003877 res = utimensat(AT_FDCWD, path, buf, 0);
3878#elif defined(HAVE_UTIMES)
Larry Hastings76ad59b2012-05-03 00:30:07 -07003879 UA_TO_TIMEVAL(ua, buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003880 res = utimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003881#elif defined(HAVE_UTIME_H)
3882 /* XXX should define struct utimbuf instead, above */
Larry Hastings76ad59b2012-05-03 00:30:07 -07003883 UA_TO_UTIMBUF(ua, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003884 res = utime(path, &buf);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003885#else
Larry Hastings76ad59b2012-05-03 00:30:07 -07003886 UA_TO_TIME_T(ua, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003887 res = utime(path, buf);
3888#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003889 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003890 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07003891
Victor Stinner8c62be82010-05-06 00:08:46 +00003892 if (res < 0) {
3893 return posix_error_with_allocated_filename(opath);
3894 }
3895 Py_DECREF(opath);
Larry Hastings76ad59b2012-05-03 00:30:07 -07003896 Py_RETURN_NONE;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003897#undef UTIME_EXTRACT
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003898#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003899}
3900
Ross Lagerwall7807c352011-03-17 20:20:30 +02003901#ifdef HAVE_FUTIMES
3902PyDoc_STRVAR(posix_futimes__doc__,
Larry Hastings76ad59b2012-05-03 00:30:07 -07003903"futimes(fd[, times=(atime, mtime), *, ns=(atime_ns, mtime_ns)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003904Set the access and modified time of the file specified by the file\n\
Larry Hastings76ad59b2012-05-03 00:30:07 -07003905descriptor fd. See utime for the semantics of the times and ns parameters.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02003906
3907static PyObject *
Larry Hastings76ad59b2012-05-03 00:30:07 -07003908posix_futimes(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02003909{
3910 int res, fd;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003911
Larry Hastings76ad59b2012-05-03 00:30:07 -07003912 DECLARE_UA(ua, "futimes");
3913
3914 ua.path_format = 'i';
3915 ua.path = (PyObject **)&fd;
3916 ua.first_argument_name = "fd";
3917
Larry Hastingsb3336402012-05-04 02:31:57 -07003918 if (utime_read_time_arguments(&ua) != utime_success)
Ross Lagerwall7807c352011-03-17 20:20:30 +02003919 return NULL;
3920
Larry Hastings76ad59b2012-05-03 00:30:07 -07003921 if (ua.now) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003922 Py_BEGIN_ALLOW_THREADS
3923 res = futimes(fd, NULL);
3924 Py_END_ALLOW_THREADS
3925 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003926 else {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003927 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003928 {
3929#ifdef HAVE_FUTIMENS
Larry Hastings76ad59b2012-05-03 00:30:07 -07003930 UA_TO_TIMESPEC(ua, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003931 res = futimens(fd, buf);
3932#else
Larry Hastings76ad59b2012-05-03 00:30:07 -07003933 UA_TO_TIMEVAL(ua, buf);
Ross Lagerwall7807c352011-03-17 20:20:30 +02003934 res = futimes(fd, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003935#endif
3936 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003937 Py_END_ALLOW_THREADS
3938 }
3939 if (res < 0)
3940 return posix_error();
3941 Py_RETURN_NONE;
3942}
3943#endif
3944
3945#ifdef HAVE_LUTIMES
3946PyDoc_STRVAR(posix_lutimes__doc__,
Larry Hastings76ad59b2012-05-03 00:30:07 -07003947"lutimes(path[, times=(atime, mtime), *, ns=(atime_ns, mtime_ns)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003948Like utime(), but if path is a symbolic link, it is not dereferenced.");
3949
3950static PyObject *
Larry Hastings76ad59b2012-05-03 00:30:07 -07003951posix_lutimes(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02003952{
Brian Curtinc1b65d12011-11-07 14:18:54 -06003953 PyObject *opath;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003954 const char *path;
3955 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003956
Larry Hastings76ad59b2012-05-03 00:30:07 -07003957 DECLARE_UA(ua, "lutimes");
3958
3959 ua.path_format = 'O';
3960 ua.path = &opath;
3961 ua.converter = PyUnicode_FSConverter;
3962
Larry Hastingsb3336402012-05-04 02:31:57 -07003963 if (utime_read_time_arguments(&ua) != utime_success)
Ross Lagerwall7807c352011-03-17 20:20:30 +02003964 return NULL;
3965 path = PyBytes_AsString(opath);
Larry Hastings76ad59b2012-05-03 00:30:07 -07003966
3967 if (ua.now) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003968 /* optional time values not given */
3969 Py_BEGIN_ALLOW_THREADS
3970 res = lutimes(path, NULL);
3971 Py_END_ALLOW_THREADS
3972 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003973 else {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003974 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003975 {
3976#ifdef HAVE_UTIMENSAT
Larry Hastings76ad59b2012-05-03 00:30:07 -07003977 UA_TO_TIMESPEC(ua, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003978 res = utimensat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
3979#else
Larry Hastings76ad59b2012-05-03 00:30:07 -07003980 UA_TO_TIMEVAL(ua, buf);
Ross Lagerwall7807c352011-03-17 20:20:30 +02003981 res = lutimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003982#endif
3983 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003984 Py_END_ALLOW_THREADS
3985 }
3986 Py_DECREF(opath);
3987 if (res < 0)
3988 return posix_error();
3989 Py_RETURN_NONE;
3990}
3991#endif
3992
Guido van Rossum3b066191991-06-04 19:40:25 +00003993/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003994
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003995PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003996"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003997Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003998
Barry Warsaw53699e91996-12-10 23:23:01 +00003999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004000posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004001{
Victor Stinner8c62be82010-05-06 00:08:46 +00004002 int sts;
4003 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4004 return NULL;
4005 _exit(sts);
4006 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004007}
4008
Martin v. Löwis114619e2002-10-07 06:44:21 +00004009#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4010static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004011free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004012{
Victor Stinner8c62be82010-05-06 00:08:46 +00004013 Py_ssize_t i;
4014 for (i = 0; i < count; i++)
4015 PyMem_Free(array[i]);
4016 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004017}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004018
Antoine Pitrou69f71142009-05-24 21:25:49 +00004019static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004020int fsconvert_strdup(PyObject *o, char**out)
4021{
Victor Stinner8c62be82010-05-06 00:08:46 +00004022 PyObject *bytes;
4023 Py_ssize_t size;
4024 if (!PyUnicode_FSConverter(o, &bytes))
4025 return 0;
4026 size = PyBytes_GET_SIZE(bytes);
4027 *out = PyMem_Malloc(size+1);
4028 if (!*out)
4029 return 0;
4030 memcpy(*out, PyBytes_AsString(bytes), size+1);
4031 Py_DECREF(bytes);
4032 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004033}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004034#endif
4035
Ross Lagerwall7807c352011-03-17 20:20:30 +02004036#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004037static char**
4038parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4039{
Victor Stinner8c62be82010-05-06 00:08:46 +00004040 char **envlist;
4041 Py_ssize_t i, pos, envc;
4042 PyObject *keys=NULL, *vals=NULL;
4043 PyObject *key, *val, *key2, *val2;
4044 char *p, *k, *v;
4045 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004046
Victor Stinner8c62be82010-05-06 00:08:46 +00004047 i = PyMapping_Size(env);
4048 if (i < 0)
4049 return NULL;
4050 envlist = PyMem_NEW(char *, i + 1);
4051 if (envlist == NULL) {
4052 PyErr_NoMemory();
4053 return NULL;
4054 }
4055 envc = 0;
4056 keys = PyMapping_Keys(env);
4057 vals = PyMapping_Values(env);
4058 if (!keys || !vals)
4059 goto error;
4060 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4061 PyErr_Format(PyExc_TypeError,
4062 "env.keys() or env.values() is not a list");
4063 goto error;
4064 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004065
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 for (pos = 0; pos < i; pos++) {
4067 key = PyList_GetItem(keys, pos);
4068 val = PyList_GetItem(vals, pos);
4069 if (!key || !val)
4070 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004071
Victor Stinner8c62be82010-05-06 00:08:46 +00004072 if (PyUnicode_FSConverter(key, &key2) == 0)
4073 goto error;
4074 if (PyUnicode_FSConverter(val, &val2) == 0) {
4075 Py_DECREF(key2);
4076 goto error;
4077 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004078
4079#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004080 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4081 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004082#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004083 k = PyBytes_AsString(key2);
4084 v = PyBytes_AsString(val2);
4085 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004086
Victor Stinner8c62be82010-05-06 00:08:46 +00004087 p = PyMem_NEW(char, len);
4088 if (p == NULL) {
4089 PyErr_NoMemory();
4090 Py_DECREF(key2);
4091 Py_DECREF(val2);
4092 goto error;
4093 }
4094 PyOS_snprintf(p, len, "%s=%s", k, v);
4095 envlist[envc++] = p;
4096 Py_DECREF(key2);
4097 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004098#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004099 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004100#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004101 }
4102 Py_DECREF(vals);
4103 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004104
Victor Stinner8c62be82010-05-06 00:08:46 +00004105 envlist[envc] = 0;
4106 *envc_ptr = envc;
4107 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004108
4109error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004110 Py_XDECREF(keys);
4111 Py_XDECREF(vals);
4112 while (--envc >= 0)
4113 PyMem_DEL(envlist[envc]);
4114 PyMem_DEL(envlist);
4115 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004116}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004117
Ross Lagerwall7807c352011-03-17 20:20:30 +02004118static char**
4119parse_arglist(PyObject* argv, Py_ssize_t *argc)
4120{
4121 int i;
4122 char **argvlist = PyMem_NEW(char *, *argc+1);
4123 if (argvlist == NULL) {
4124 PyErr_NoMemory();
4125 return NULL;
4126 }
4127 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004128 PyObject* item = PySequence_ITEM(argv, i);
4129 if (item == NULL)
4130 goto fail;
4131 if (!fsconvert_strdup(item, &argvlist[i])) {
4132 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004133 goto fail;
4134 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004135 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004136 }
4137 argvlist[*argc] = NULL;
4138 return argvlist;
4139fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004140 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004141 free_string_array(argvlist, *argc);
4142 return NULL;
4143}
4144#endif
4145
4146#ifdef HAVE_EXECV
4147PyDoc_STRVAR(posix_execv__doc__,
4148"execv(path, args)\n\n\
4149Execute an executable path with arguments, replacing current process.\n\
4150\n\
4151 path: path of executable file\n\
4152 args: tuple or list of strings");
4153
4154static PyObject *
4155posix_execv(PyObject *self, PyObject *args)
4156{
4157 PyObject *opath;
4158 char *path;
4159 PyObject *argv;
4160 char **argvlist;
4161 Py_ssize_t argc;
4162
4163 /* execv has two arguments: (path, argv), where
4164 argv is a list or tuple of strings. */
4165
4166 if (!PyArg_ParseTuple(args, "O&O:execv",
4167 PyUnicode_FSConverter,
4168 &opath, &argv))
4169 return NULL;
4170 path = PyBytes_AsString(opath);
4171 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4172 PyErr_SetString(PyExc_TypeError,
4173 "execv() arg 2 must be a tuple or list");
4174 Py_DECREF(opath);
4175 return NULL;
4176 }
4177 argc = PySequence_Size(argv);
4178 if (argc < 1) {
4179 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4180 Py_DECREF(opath);
4181 return NULL;
4182 }
4183
4184 argvlist = parse_arglist(argv, &argc);
4185 if (argvlist == NULL) {
4186 Py_DECREF(opath);
4187 return NULL;
4188 }
4189
4190 execv(path, argvlist);
4191
4192 /* If we get here it's definitely an error */
4193
4194 free_string_array(argvlist, argc);
4195 Py_DECREF(opath);
4196 return posix_error();
4197}
4198
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004199PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004200"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004201Execute a path with arguments and environment, replacing current process.\n\
4202\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004203 path: path of executable file\n\
4204 args: tuple or list of arguments\n\
4205 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004206
Barry Warsaw53699e91996-12-10 23:23:01 +00004207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004208posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004209{
Victor Stinner8c62be82010-05-06 00:08:46 +00004210 PyObject *opath;
4211 char *path;
4212 PyObject *argv, *env;
4213 char **argvlist;
4214 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004215 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004216
Victor Stinner8c62be82010-05-06 00:08:46 +00004217 /* execve has three arguments: (path, argv, env), where
4218 argv is a list or tuple of strings and env is a dictionary
4219 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004220
Victor Stinner8c62be82010-05-06 00:08:46 +00004221 if (!PyArg_ParseTuple(args, "O&OO:execve",
4222 PyUnicode_FSConverter,
4223 &opath, &argv, &env))
4224 return NULL;
4225 path = PyBytes_AsString(opath);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004226 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004227 PyErr_SetString(PyExc_TypeError,
4228 "execve() arg 2 must be a tuple or list");
4229 goto fail_0;
4230 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004231 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004232 if (!PyMapping_Check(env)) {
4233 PyErr_SetString(PyExc_TypeError,
4234 "execve() arg 3 must be a mapping object");
4235 goto fail_0;
4236 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004237
Ross Lagerwall7807c352011-03-17 20:20:30 +02004238 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004239 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004240 goto fail_0;
4241 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004242
Victor Stinner8c62be82010-05-06 00:08:46 +00004243 envlist = parse_envlist(env, &envc);
4244 if (envlist == NULL)
4245 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004246
Victor Stinner8c62be82010-05-06 00:08:46 +00004247 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00004248
Victor Stinner8c62be82010-05-06 00:08:46 +00004249 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004250
Victor Stinner8c62be82010-05-06 00:08:46 +00004251 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004252
Victor Stinner8c62be82010-05-06 00:08:46 +00004253 while (--envc >= 0)
4254 PyMem_DEL(envlist[envc]);
4255 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004256 fail_1:
Ross Lagerwall7807c352011-03-17 20:20:30 +02004257 free_string_array(argvlist, argc);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004258 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004259 Py_DECREF(opath);
4260 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004261}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004262#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004263
Ross Lagerwall7807c352011-03-17 20:20:30 +02004264#ifdef HAVE_FEXECVE
4265PyDoc_STRVAR(posix_fexecve__doc__,
4266"fexecve(fd, args, env)\n\n\
4267Execute the program specified by a file descriptor with arguments and\n\
4268environment, replacing the current process.\n\
4269\n\
4270 fd: file descriptor of executable\n\
4271 args: tuple or list of arguments\n\
4272 env: dictionary of strings mapping to strings");
4273
4274static PyObject *
4275posix_fexecve(PyObject *self, PyObject *args)
4276{
4277 int fd;
4278 PyObject *argv, *env;
4279 char **argvlist;
4280 char **envlist;
4281 Py_ssize_t argc, envc;
4282
4283 if (!PyArg_ParseTuple(args, "iOO:fexecve",
4284 &fd, &argv, &env))
4285 return NULL;
4286 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4287 PyErr_SetString(PyExc_TypeError,
4288 "fexecve() arg 2 must be a tuple or list");
4289 return NULL;
4290 }
4291 argc = PySequence_Size(argv);
4292 if (!PyMapping_Check(env)) {
4293 PyErr_SetString(PyExc_TypeError,
4294 "fexecve() arg 3 must be a mapping object");
4295 return NULL;
4296 }
4297
4298 argvlist = parse_arglist(argv, &argc);
4299 if (argvlist == NULL)
4300 return NULL;
4301
4302 envlist = parse_envlist(env, &envc);
4303 if (envlist == NULL)
4304 goto fail;
4305
4306 fexecve(fd, argvlist, envlist);
4307
4308 /* If we get here it's definitely an error */
4309
4310 (void) posix_error();
4311
4312 while (--envc >= 0)
4313 PyMem_DEL(envlist[envc]);
4314 PyMem_DEL(envlist);
4315 fail:
4316 free_string_array(argvlist, argc);
4317 return NULL;
4318}
4319#endif /* HAVE_FEXECVE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004320
Guido van Rossuma1065681999-01-25 23:20:23 +00004321#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004322PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004323"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004324Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004325\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004326 mode: mode of process creation\n\
4327 path: path of executable file\n\
4328 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004329
4330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004331posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004332{
Victor Stinner8c62be82010-05-06 00:08:46 +00004333 PyObject *opath;
4334 char *path;
4335 PyObject *argv;
4336 char **argvlist;
4337 int mode, i;
4338 Py_ssize_t argc;
4339 Py_intptr_t spawnval;
4340 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004341
Victor Stinner8c62be82010-05-06 00:08:46 +00004342 /* spawnv has three arguments: (mode, path, argv), where
4343 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004344
Victor Stinner8c62be82010-05-06 00:08:46 +00004345 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4346 PyUnicode_FSConverter,
4347 &opath, &argv))
4348 return NULL;
4349 path = PyBytes_AsString(opath);
4350 if (PyList_Check(argv)) {
4351 argc = PyList_Size(argv);
4352 getitem = PyList_GetItem;
4353 }
4354 else if (PyTuple_Check(argv)) {
4355 argc = PyTuple_Size(argv);
4356 getitem = PyTuple_GetItem;
4357 }
4358 else {
4359 PyErr_SetString(PyExc_TypeError,
4360 "spawnv() arg 2 must be a tuple or list");
4361 Py_DECREF(opath);
4362 return NULL;
4363 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004364
Victor Stinner8c62be82010-05-06 00:08:46 +00004365 argvlist = PyMem_NEW(char *, argc+1);
4366 if (argvlist == NULL) {
4367 Py_DECREF(opath);
4368 return PyErr_NoMemory();
4369 }
4370 for (i = 0; i < argc; i++) {
4371 if (!fsconvert_strdup((*getitem)(argv, i),
4372 &argvlist[i])) {
4373 free_string_array(argvlist, i);
4374 PyErr_SetString(
4375 PyExc_TypeError,
4376 "spawnv() arg 2 must contain only strings");
4377 Py_DECREF(opath);
4378 return NULL;
4379 }
4380 }
4381 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004382
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004383#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004384 Py_BEGIN_ALLOW_THREADS
4385 spawnval = spawnv(mode, path, argvlist);
4386 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004387#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004388 if (mode == _OLD_P_OVERLAY)
4389 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004390
Victor Stinner8c62be82010-05-06 00:08:46 +00004391 Py_BEGIN_ALLOW_THREADS
4392 spawnval = _spawnv(mode, path, argvlist);
4393 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004394#endif
Tim Peters5aa91602002-01-30 05:46:57 +00004395
Victor Stinner8c62be82010-05-06 00:08:46 +00004396 free_string_array(argvlist, argc);
4397 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004398
Victor Stinner8c62be82010-05-06 00:08:46 +00004399 if (spawnval == -1)
4400 return posix_error();
4401 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004402#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004403 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004404#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004405 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004406#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004407}
4408
4409
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004410PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004411"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004412Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004413\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004414 mode: mode of process creation\n\
4415 path: path of executable file\n\
4416 args: tuple or list of arguments\n\
4417 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004418
4419static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004420posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004421{
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 PyObject *opath;
4423 char *path;
4424 PyObject *argv, *env;
4425 char **argvlist;
4426 char **envlist;
4427 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004428 int mode;
4429 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004430 Py_intptr_t spawnval;
4431 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4432 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004433
Victor Stinner8c62be82010-05-06 00:08:46 +00004434 /* spawnve has four arguments: (mode, path, argv, env), where
4435 argv is a list or tuple of strings and env is a dictionary
4436 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004437
Victor Stinner8c62be82010-05-06 00:08:46 +00004438 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4439 PyUnicode_FSConverter,
4440 &opath, &argv, &env))
4441 return NULL;
4442 path = PyBytes_AsString(opath);
4443 if (PyList_Check(argv)) {
4444 argc = PyList_Size(argv);
4445 getitem = PyList_GetItem;
4446 }
4447 else if (PyTuple_Check(argv)) {
4448 argc = PyTuple_Size(argv);
4449 getitem = PyTuple_GetItem;
4450 }
4451 else {
4452 PyErr_SetString(PyExc_TypeError,
4453 "spawnve() arg 2 must be a tuple or list");
4454 goto fail_0;
4455 }
4456 if (!PyMapping_Check(env)) {
4457 PyErr_SetString(PyExc_TypeError,
4458 "spawnve() arg 3 must be a mapping object");
4459 goto fail_0;
4460 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004461
Victor Stinner8c62be82010-05-06 00:08:46 +00004462 argvlist = PyMem_NEW(char *, argc+1);
4463 if (argvlist == NULL) {
4464 PyErr_NoMemory();
4465 goto fail_0;
4466 }
4467 for (i = 0; i < argc; i++) {
4468 if (!fsconvert_strdup((*getitem)(argv, i),
4469 &argvlist[i]))
4470 {
4471 lastarg = i;
4472 goto fail_1;
4473 }
4474 }
4475 lastarg = argc;
4476 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004477
Victor Stinner8c62be82010-05-06 00:08:46 +00004478 envlist = parse_envlist(env, &envc);
4479 if (envlist == NULL)
4480 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004481
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004482#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004483 Py_BEGIN_ALLOW_THREADS
4484 spawnval = spawnve(mode, path, argvlist, envlist);
4485 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004486#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004487 if (mode == _OLD_P_OVERLAY)
4488 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004489
Victor Stinner8c62be82010-05-06 00:08:46 +00004490 Py_BEGIN_ALLOW_THREADS
4491 spawnval = _spawnve(mode, path, argvlist, envlist);
4492 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004493#endif
Tim Peters25059d32001-12-07 20:35:43 +00004494
Victor Stinner8c62be82010-05-06 00:08:46 +00004495 if (spawnval == -1)
4496 (void) posix_error();
4497 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004498#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004499 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004500#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004501 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004502#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004503
Victor Stinner8c62be82010-05-06 00:08:46 +00004504 while (--envc >= 0)
4505 PyMem_DEL(envlist[envc]);
4506 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004507 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004509 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004510 Py_DECREF(opath);
4511 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004512}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004513
4514/* OS/2 supports spawnvp & spawnvpe natively */
4515#if defined(PYOS_OS2)
4516PyDoc_STRVAR(posix_spawnvp__doc__,
4517"spawnvp(mode, file, args)\n\n\
4518Execute the program 'file' in a new process, using the environment\n\
4519search path to find the file.\n\
4520\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004521 mode: mode of process creation\n\
4522 file: executable file name\n\
4523 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004524
4525static PyObject *
4526posix_spawnvp(PyObject *self, PyObject *args)
4527{
Victor Stinner8c62be82010-05-06 00:08:46 +00004528 PyObject *opath;
4529 char *path;
4530 PyObject *argv;
4531 char **argvlist;
4532 int mode, i, argc;
4533 Py_intptr_t spawnval;
4534 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004535
Victor Stinner8c62be82010-05-06 00:08:46 +00004536 /* spawnvp has three arguments: (mode, path, argv), where
4537 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004538
Victor Stinner8c62be82010-05-06 00:08:46 +00004539 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
4540 PyUnicode_FSConverter,
4541 &opath, &argv))
4542 return NULL;
4543 path = PyBytes_AsString(opath);
4544 if (PyList_Check(argv)) {
4545 argc = PyList_Size(argv);
4546 getitem = PyList_GetItem;
4547 }
4548 else if (PyTuple_Check(argv)) {
4549 argc = PyTuple_Size(argv);
4550 getitem = PyTuple_GetItem;
4551 }
4552 else {
4553 PyErr_SetString(PyExc_TypeError,
4554 "spawnvp() arg 2 must be a tuple or list");
4555 Py_DECREF(opath);
4556 return NULL;
4557 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004558
Victor Stinner8c62be82010-05-06 00:08:46 +00004559 argvlist = PyMem_NEW(char *, argc+1);
4560 if (argvlist == NULL) {
4561 Py_DECREF(opath);
4562 return PyErr_NoMemory();
4563 }
4564 for (i = 0; i < argc; i++) {
4565 if (!fsconvert_strdup((*getitem)(argv, i),
4566 &argvlist[i])) {
4567 free_string_array(argvlist, i);
4568 PyErr_SetString(
4569 PyExc_TypeError,
4570 "spawnvp() arg 2 must contain only strings");
4571 Py_DECREF(opath);
4572 return NULL;
4573 }
4574 }
4575 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004576
Victor Stinner8c62be82010-05-06 00:08:46 +00004577 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004578#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004579 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004580#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004581 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004582#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004583 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004584
Victor Stinner8c62be82010-05-06 00:08:46 +00004585 free_string_array(argvlist, argc);
4586 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004587
Victor Stinner8c62be82010-05-06 00:08:46 +00004588 if (spawnval == -1)
4589 return posix_error();
4590 else
4591 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004592}
4593
4594
4595PyDoc_STRVAR(posix_spawnvpe__doc__,
4596"spawnvpe(mode, file, args, env)\n\n\
4597Execute the program 'file' in a new process, using the environment\n\
4598search path to find the file.\n\
4599\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004600 mode: mode of process creation\n\
4601 file: executable file name\n\
4602 args: tuple or list of arguments\n\
4603 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004604
4605static PyObject *
4606posix_spawnvpe(PyObject *self, PyObject *args)
4607{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02004608 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00004609 char *path;
4610 PyObject *argv, *env;
4611 char **argvlist;
4612 char **envlist;
4613 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004614 int mode;
4615 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004616 Py_intptr_t spawnval;
4617 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4618 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004619
Victor Stinner8c62be82010-05-06 00:08:46 +00004620 /* spawnvpe has four arguments: (mode, path, argv, env), where
4621 argv is a list or tuple of strings and env is a dictionary
4622 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004623
Victor Stinner8c62be82010-05-06 00:08:46 +00004624 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4625 PyUnicode_FSConverter,
4626 &opath, &argv, &env))
4627 return NULL;
4628 path = PyBytes_AsString(opath);
4629 if (PyList_Check(argv)) {
4630 argc = PyList_Size(argv);
4631 getitem = PyList_GetItem;
4632 }
4633 else if (PyTuple_Check(argv)) {
4634 argc = PyTuple_Size(argv);
4635 getitem = PyTuple_GetItem;
4636 }
4637 else {
4638 PyErr_SetString(PyExc_TypeError,
4639 "spawnvpe() arg 2 must be a tuple or list");
4640 goto fail_0;
4641 }
4642 if (!PyMapping_Check(env)) {
4643 PyErr_SetString(PyExc_TypeError,
4644 "spawnvpe() arg 3 must be a mapping object");
4645 goto fail_0;
4646 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004647
Victor Stinner8c62be82010-05-06 00:08:46 +00004648 argvlist = PyMem_NEW(char *, argc+1);
4649 if (argvlist == NULL) {
4650 PyErr_NoMemory();
4651 goto fail_0;
4652 }
4653 for (i = 0; i < argc; i++) {
4654 if (!fsconvert_strdup((*getitem)(argv, i),
4655 &argvlist[i]))
4656 {
4657 lastarg = i;
4658 goto fail_1;
4659 }
4660 }
4661 lastarg = argc;
4662 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004663
Victor Stinner8c62be82010-05-06 00:08:46 +00004664 envlist = parse_envlist(env, &envc);
4665 if (envlist == NULL)
4666 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004667
Victor Stinner8c62be82010-05-06 00:08:46 +00004668 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004669#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004670 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004671#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004672 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004673#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004674 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004675
Victor Stinner8c62be82010-05-06 00:08:46 +00004676 if (spawnval == -1)
4677 (void) posix_error();
4678 else
4679 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004680
Victor Stinner8c62be82010-05-06 00:08:46 +00004681 while (--envc >= 0)
4682 PyMem_DEL(envlist[envc]);
4683 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004684 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004685 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004686 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004687 Py_DECREF(opath);
4688 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004689}
4690#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004691#endif /* HAVE_SPAWNV */
4692
4693
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004694#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004695PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004696"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004697Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4698\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004699Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004700
4701static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004702posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004703{
Victor Stinner8c62be82010-05-06 00:08:46 +00004704 pid_t pid;
4705 int result = 0;
4706 _PyImport_AcquireLock();
4707 pid = fork1();
4708 if (pid == 0) {
4709 /* child: this clobbers and resets the import lock. */
4710 PyOS_AfterFork();
4711 } else {
4712 /* parent: release the import lock. */
4713 result = _PyImport_ReleaseLock();
4714 }
4715 if (pid == -1)
4716 return posix_error();
4717 if (result < 0) {
4718 /* Don't clobber the OSError if the fork failed. */
4719 PyErr_SetString(PyExc_RuntimeError,
4720 "not holding the import lock");
4721 return NULL;
4722 }
4723 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004724}
4725#endif
4726
4727
Guido van Rossumad0ee831995-03-01 10:34:45 +00004728#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004729PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004730"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004731Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004732Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004733
Barry Warsaw53699e91996-12-10 23:23:01 +00004734static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004735posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004736{
Victor Stinner8c62be82010-05-06 00:08:46 +00004737 pid_t pid;
4738 int result = 0;
4739 _PyImport_AcquireLock();
4740 pid = fork();
4741 if (pid == 0) {
4742 /* child: this clobbers and resets the import lock. */
4743 PyOS_AfterFork();
4744 } else {
4745 /* parent: release the import lock. */
4746 result = _PyImport_ReleaseLock();
4747 }
4748 if (pid == -1)
4749 return posix_error();
4750 if (result < 0) {
4751 /* Don't clobber the OSError if the fork failed. */
4752 PyErr_SetString(PyExc_RuntimeError,
4753 "not holding the import lock");
4754 return NULL;
4755 }
4756 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004757}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004758#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004759
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004760#ifdef HAVE_SCHED_H
4761
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004762#ifdef HAVE_SCHED_GET_PRIORITY_MAX
4763
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004764PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
4765"sched_get_priority_max(policy)\n\n\
4766Get the maximum scheduling priority for *policy*.");
4767
4768static PyObject *
4769posix_sched_get_priority_max(PyObject *self, PyObject *args)
4770{
4771 int policy, max;
4772
4773 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
4774 return NULL;
4775 max = sched_get_priority_max(policy);
4776 if (max < 0)
4777 return posix_error();
4778 return PyLong_FromLong(max);
4779}
4780
4781PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
4782"sched_get_priority_min(policy)\n\n\
4783Get the minimum scheduling priority for *policy*.");
4784
4785static PyObject *
4786posix_sched_get_priority_min(PyObject *self, PyObject *args)
4787{
4788 int policy, min;
4789
4790 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
4791 return NULL;
4792 min = sched_get_priority_min(policy);
4793 if (min < 0)
4794 return posix_error();
4795 return PyLong_FromLong(min);
4796}
4797
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004798#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
4799
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004800#ifdef HAVE_SCHED_SETSCHEDULER
4801
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004802PyDoc_STRVAR(posix_sched_getscheduler__doc__,
4803"sched_getscheduler(pid)\n\n\
4804Get the scheduling policy for the process with a PID of *pid*.\n\
4805Passing a PID of 0 returns the scheduling policy for the calling process.");
4806
4807static PyObject *
4808posix_sched_getscheduler(PyObject *self, PyObject *args)
4809{
4810 pid_t pid;
4811 int policy;
4812
4813 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
4814 return NULL;
4815 policy = sched_getscheduler(pid);
4816 if (policy < 0)
4817 return posix_error();
4818 return PyLong_FromLong(policy);
4819}
4820
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004821#endif
4822
4823#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
4824
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004825static PyObject *
4826sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4827{
4828 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05004829 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004830
4831 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
4832 return NULL;
4833 res = PyStructSequence_New(type);
4834 if (!res)
4835 return NULL;
4836 Py_INCREF(priority);
4837 PyStructSequence_SET_ITEM(res, 0, priority);
4838 return res;
4839}
4840
4841PyDoc_STRVAR(sched_param__doc__,
4842"sched_param(sched_priority): A scheduling parameter.\n\n\
4843Current has only one field: sched_priority");
4844
4845static PyStructSequence_Field sched_param_fields[] = {
4846 {"sched_priority", "the scheduling priority"},
4847 {0}
4848};
4849
4850static PyStructSequence_Desc sched_param_desc = {
4851 "sched_param", /* name */
4852 sched_param__doc__, /* doc */
4853 sched_param_fields,
4854 1
4855};
4856
4857static int
4858convert_sched_param(PyObject *param, struct sched_param *res)
4859{
4860 long priority;
4861
4862 if (Py_TYPE(param) != &SchedParamType) {
4863 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
4864 return 0;
4865 }
4866 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
4867 if (priority == -1 && PyErr_Occurred())
4868 return 0;
4869 if (priority > INT_MAX || priority < INT_MIN) {
4870 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
4871 return 0;
4872 }
4873 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
4874 return 1;
4875}
4876
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004877#endif
4878
4879#ifdef HAVE_SCHED_SETSCHEDULER
4880
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004881PyDoc_STRVAR(posix_sched_setscheduler__doc__,
4882"sched_setscheduler(pid, policy, param)\n\n\
4883Set the scheduling policy, *policy*, for *pid*.\n\
4884If *pid* is 0, the calling process is changed.\n\
4885*param* is an instance of sched_param.");
4886
4887static PyObject *
4888posix_sched_setscheduler(PyObject *self, PyObject *args)
4889{
4890 pid_t pid;
4891 int policy;
4892 struct sched_param param;
4893
4894 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
4895 &pid, &policy, &convert_sched_param, &param))
4896 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02004897
4898 /*
Jesus Cea54b01492011-09-10 01:53:19 +02004899 ** sched_setscheduler() returns 0 in Linux, but the previous
4900 ** scheduling policy under Solaris/Illumos, and others.
4901 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02004902 */
4903 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004904 return posix_error();
4905 Py_RETURN_NONE;
4906}
4907
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004908#endif
4909
4910#ifdef HAVE_SCHED_SETPARAM
4911
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004912PyDoc_STRVAR(posix_sched_getparam__doc__,
4913"sched_getparam(pid) -> sched_param\n\n\
4914Returns scheduling parameters for the process with *pid* as an instance of the\n\
4915sched_param class. A PID of 0 means the calling process.");
4916
4917static PyObject *
4918posix_sched_getparam(PyObject *self, PyObject *args)
4919{
4920 pid_t pid;
4921 struct sched_param param;
4922 PyObject *res, *priority;
4923
4924 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
4925 return NULL;
4926 if (sched_getparam(pid, &param))
4927 return posix_error();
4928 res = PyStructSequence_New(&SchedParamType);
4929 if (!res)
4930 return NULL;
4931 priority = PyLong_FromLong(param.sched_priority);
4932 if (!priority) {
4933 Py_DECREF(res);
4934 return NULL;
4935 }
4936 PyStructSequence_SET_ITEM(res, 0, priority);
4937 return res;
4938}
4939
4940PyDoc_STRVAR(posix_sched_setparam__doc__,
4941"sched_setparam(pid, param)\n\n\
4942Set scheduling parameters for a process with PID *pid*.\n\
4943A PID of 0 means the calling process.");
4944
4945static PyObject *
4946posix_sched_setparam(PyObject *self, PyObject *args)
4947{
4948 pid_t pid;
4949 struct sched_param param;
4950
4951 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
4952 &pid, &convert_sched_param, &param))
4953 return NULL;
4954 if (sched_setparam(pid, &param))
4955 return posix_error();
4956 Py_RETURN_NONE;
4957}
4958
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004959#endif
4960
4961#ifdef HAVE_SCHED_RR_GET_INTERVAL
4962
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004963PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
4964"sched_rr_get_interval(pid) -> float\n\n\
4965Return the round-robin quantum for the process with PID *pid* in seconds.");
4966
4967static PyObject *
4968posix_sched_rr_get_interval(PyObject *self, PyObject *args)
4969{
4970 pid_t pid;
4971 struct timespec interval;
4972
4973 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
4974 return NULL;
4975 if (sched_rr_get_interval(pid, &interval))
4976 return posix_error();
4977 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
4978}
4979
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004980#endif
4981
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004982PyDoc_STRVAR(posix_sched_yield__doc__,
4983"sched_yield()\n\n\
4984Voluntarily relinquish the CPU.");
4985
4986static PyObject *
4987posix_sched_yield(PyObject *self, PyObject *noargs)
4988{
4989 if (sched_yield())
4990 return posix_error();
4991 Py_RETURN_NONE;
4992}
4993
Benjamin Peterson2740af82011-08-02 17:41:34 -05004994#ifdef HAVE_SCHED_SETAFFINITY
4995
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004996typedef struct {
4997 PyObject_HEAD;
4998 Py_ssize_t size;
4999 int ncpus;
5000 cpu_set_t *set;
5001} Py_cpu_set;
5002
5003static PyTypeObject cpu_set_type;
5004
5005static void
5006cpu_set_dealloc(Py_cpu_set *set)
5007{
5008 assert(set->set);
5009 CPU_FREE(set->set);
5010 Py_TYPE(set)->tp_free(set);
5011}
5012
5013static Py_cpu_set *
5014make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
5015{
5016 Py_cpu_set *set;
5017
5018 if (size < 0) {
5019 PyErr_SetString(PyExc_ValueError, "negative size");
5020 return NULL;
5021 }
5022 set = (Py_cpu_set *)type->tp_alloc(type, 0);
5023 if (!set)
5024 return NULL;
5025 set->ncpus = size;
5026 set->size = CPU_ALLOC_SIZE(size);
5027 set->set = CPU_ALLOC(size);
5028 if (!set->set) {
5029 type->tp_free(set);
5030 PyErr_NoMemory();
5031 return NULL;
5032 }
5033 CPU_ZERO_S(set->size, set->set);
5034 return set;
5035}
5036
5037static PyObject *
5038cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5039{
5040 int size;
5041
5042 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
5043 !PyArg_ParseTuple(args, "i:cpu_set", &size))
5044 return NULL;
5045 return (PyObject *)make_new_cpu_set(type, size);
5046}
5047
5048static PyObject *
5049cpu_set_repr(Py_cpu_set *set)
5050{
5051 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02005052}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005053
5054static Py_ssize_t
5055cpu_set_len(Py_cpu_set *set)
5056{
5057 return set->ncpus;
5058}
5059
5060static int
5061_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
5062{
5063 int cpu;
5064 if (!PyArg_ParseTuple(args, requester, &cpu))
5065 return -1;
5066 if (cpu < 0) {
5067 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
5068 return -1;
5069 }
5070 if (cpu >= set->ncpus) {
5071 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
5072 return -1;
5073 }
5074 return cpu;
5075}
5076
5077PyDoc_STRVAR(cpu_set_set_doc,
5078"cpu_set.set(i)\n\n\
5079Add CPU *i* to the set.");
5080
5081static PyObject *
5082cpu_set_set(Py_cpu_set *set, PyObject *args)
5083{
5084 int cpu = _get_cpu(set, "i|set", args);
5085 if (cpu == -1)
5086 return NULL;
5087 CPU_SET_S(cpu, set->size, set->set);
5088 Py_RETURN_NONE;
5089}
5090
5091PyDoc_STRVAR(cpu_set_count_doc,
5092"cpu_set.count() -> int\n\n\
5093Return the number of CPUs active in the set.");
5094
5095static PyObject *
5096cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5097{
5098 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5099}
5100
5101PyDoc_STRVAR(cpu_set_clear_doc,
5102"cpu_set.clear(i)\n\n\
5103Remove CPU *i* from the set.");
5104
5105static PyObject *
5106cpu_set_clear(Py_cpu_set *set, PyObject *args)
5107{
5108 int cpu = _get_cpu(set, "i|clear", args);
5109 if (cpu == -1)
5110 return NULL;
5111 CPU_CLR_S(cpu, set->size, set->set);
5112 Py_RETURN_NONE;
5113}
5114
5115PyDoc_STRVAR(cpu_set_isset_doc,
5116"cpu_set.isset(i) -> bool\n\n\
5117Test if CPU *i* is in the set.");
5118
5119static PyObject *
5120cpu_set_isset(Py_cpu_set *set, PyObject *args)
5121{
5122 int cpu = _get_cpu(set, "i|isset", args);
5123 if (cpu == -1)
5124 return NULL;
5125 if (CPU_ISSET_S(cpu, set->size, set->set))
5126 Py_RETURN_TRUE;
5127 Py_RETURN_FALSE;
5128}
5129
5130PyDoc_STRVAR(cpu_set_zero_doc,
5131"cpu_set.zero()\n\n\
5132Clear the cpu_set.");
5133
5134static PyObject *
5135cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5136{
5137 CPU_ZERO_S(set->size, set->set);
5138 Py_RETURN_NONE;
5139}
5140
5141static PyObject *
5142cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5143{
5144 int eq;
5145
Brian Curtindfc80e32011-08-10 20:28:54 -05005146 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5147 Py_RETURN_NOTIMPLEMENTED;
5148
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005149 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5150 if ((op == Py_EQ) ? eq : !eq)
5151 Py_RETURN_TRUE;
5152 else
5153 Py_RETURN_FALSE;
5154}
5155
5156#define CPU_SET_BINOP(name, op) \
5157 static PyObject * \
5158 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5159 if (res) { \
5160 Py_INCREF(res); \
5161 } \
5162 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005163 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005164 if (!res) \
5165 return NULL; \
5166 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005167 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005168 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005169 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005170 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005171 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005172 op(res->size, res->set, left->set, right->set); \
5173 return (PyObject *)res; \
5174 } \
5175 static PyObject * \
5176 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5177 return do_cpu_set_##name(left, right, NULL); \
5178 } \
5179 static PyObject * \
5180 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5181 return do_cpu_set_##name(left, right, left); \
5182 } \
5183
5184CPU_SET_BINOP(and, CPU_AND_S)
5185CPU_SET_BINOP(or, CPU_OR_S)
5186CPU_SET_BINOP(xor, CPU_XOR_S)
5187#undef CPU_SET_BINOP
5188
5189PyDoc_STRVAR(cpu_set_doc,
5190"cpu_set(size)\n\n\
5191Create an empty mask of CPUs.");
5192
5193static PyNumberMethods cpu_set_as_number = {
5194 0, /*nb_add*/
5195 0, /*nb_subtract*/
5196 0, /*nb_multiply*/
5197 0, /*nb_remainder*/
5198 0, /*nb_divmod*/
5199 0, /*nb_power*/
5200 0, /*nb_negative*/
5201 0, /*nb_positive*/
5202 0, /*nb_absolute*/
5203 0, /*nb_bool*/
5204 0, /*nb_invert*/
5205 0, /*nb_lshift*/
5206 0, /*nb_rshift*/
5207 (binaryfunc)cpu_set_and, /*nb_and*/
5208 (binaryfunc)cpu_set_xor, /*nb_xor*/
5209 (binaryfunc)cpu_set_or, /*nb_or*/
5210 0, /*nb_int*/
5211 0, /*nb_reserved*/
5212 0, /*nb_float*/
5213 0, /*nb_inplace_add*/
5214 0, /*nb_inplace_subtract*/
5215 0, /*nb_inplace_multiply*/
5216 0, /*nb_inplace_remainder*/
5217 0, /*nb_inplace_power*/
5218 0, /*nb_inplace_lshift*/
5219 0, /*nb_inplace_rshift*/
5220 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5221 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5222 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5223};
5224
5225static PySequenceMethods cpu_set_as_sequence = {
5226 (lenfunc)cpu_set_len, /* sq_length */
5227};
5228
5229static PyMethodDef cpu_set_methods[] = {
5230 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5231 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5232 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5233 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5234 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5235 {NULL, NULL} /* sentinel */
5236};
5237
5238static PyTypeObject cpu_set_type = {
5239 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5240 "posix.cpu_set", /* tp_name */
5241 sizeof(Py_cpu_set), /* tp_basicsize */
5242 0, /* tp_itemsize */
5243 /* methods */
5244 (destructor)cpu_set_dealloc, /* tp_dealloc */
5245 0, /* tp_print */
5246 0, /* tp_getattr */
5247 0, /* tp_setattr */
5248 0, /* tp_reserved */
5249 (reprfunc)cpu_set_repr, /* tp_repr */
5250 &cpu_set_as_number, /* tp_as_number */
5251 &cpu_set_as_sequence, /* tp_as_sequence */
5252 0, /* tp_as_mapping */
5253 PyObject_HashNotImplemented, /* tp_hash */
5254 0, /* tp_call */
5255 0, /* tp_str */
5256 PyObject_GenericGetAttr, /* tp_getattro */
5257 0, /* tp_setattro */
5258 0, /* tp_as_buffer */
5259 Py_TPFLAGS_DEFAULT, /* tp_flags */
5260 cpu_set_doc, /* tp_doc */
5261 0, /* tp_traverse */
5262 0, /* tp_clear */
5263 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5264 0, /* tp_weaklistoffset */
5265 0, /* tp_iter */
5266 0, /* tp_iternext */
5267 cpu_set_methods, /* tp_methods */
5268 0, /* tp_members */
5269 0, /* tp_getset */
5270 0, /* tp_base */
5271 0, /* tp_dict */
5272 0, /* tp_descr_get */
5273 0, /* tp_descr_set */
5274 0, /* tp_dictoffset */
5275 0, /* tp_init */
5276 PyType_GenericAlloc, /* tp_alloc */
5277 cpu_set_new, /* tp_new */
5278 PyObject_Del, /* tp_free */
5279};
5280
5281PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5282"sched_setaffinity(pid, cpu_set)\n\n\
5283Set the affinity of the process with PID *pid* to *cpu_set*.");
5284
5285static PyObject *
5286posix_sched_setaffinity(PyObject *self, PyObject *args)
5287{
5288 pid_t pid;
5289 Py_cpu_set *cpu_set;
5290
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005291 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005292 &pid, &cpu_set_type, &cpu_set))
5293 return NULL;
5294 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5295 return posix_error();
5296 Py_RETURN_NONE;
5297}
5298
5299PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5300"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5301Return the affinity of the process with PID *pid*.\n\
5302The returned cpu_set will be of size *ncpus*.");
5303
5304static PyObject *
5305posix_sched_getaffinity(PyObject *self, PyObject *args)
5306{
5307 pid_t pid;
5308 int ncpus;
5309 Py_cpu_set *res;
5310
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005311 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005312 &pid, &ncpus))
5313 return NULL;
5314 res = make_new_cpu_set(&cpu_set_type, ncpus);
5315 if (!res)
5316 return NULL;
5317 if (sched_getaffinity(pid, res->size, res->set)) {
5318 Py_DECREF(res);
5319 return posix_error();
5320 }
5321 return (PyObject *)res;
5322}
5323
Benjamin Peterson2740af82011-08-02 17:41:34 -05005324#endif /* HAVE_SCHED_SETAFFINITY */
5325
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005326#endif /* HAVE_SCHED_H */
5327
Neal Norwitzb59798b2003-03-21 01:43:31 +00005328/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005329/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5330#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005331#define DEV_PTY_FILE "/dev/ptc"
5332#define HAVE_DEV_PTMX
5333#else
5334#define DEV_PTY_FILE "/dev/ptmx"
5335#endif
5336
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005337#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005338#ifdef HAVE_PTY_H
5339#include <pty.h>
5340#else
5341#ifdef HAVE_LIBUTIL_H
5342#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005343#else
5344#ifdef HAVE_UTIL_H
5345#include <util.h>
5346#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005347#endif /* HAVE_LIBUTIL_H */
5348#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005349#ifdef HAVE_STROPTS_H
5350#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005351#endif
5352#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005353
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005354#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005355PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005356"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005357Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005358
5359static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005360posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005361{
Victor Stinner8c62be82010-05-06 00:08:46 +00005362 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005363#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005364 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005365#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005366#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005367 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005368#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005369 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005370#endif
5371#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005372
Thomas Wouters70c21a12000-07-14 14:28:33 +00005373#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005374 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5375 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005376#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005377 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5378 if (slave_name == NULL)
5379 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005380
Victor Stinner8c62be82010-05-06 00:08:46 +00005381 slave_fd = open(slave_name, O_RDWR);
5382 if (slave_fd < 0)
5383 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005384#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5386 if (master_fd < 0)
5387 return posix_error();
5388 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5389 /* change permission of slave */
5390 if (grantpt(master_fd) < 0) {
5391 PyOS_setsig(SIGCHLD, sig_saved);
5392 return posix_error();
5393 }
5394 /* unlock slave */
5395 if (unlockpt(master_fd) < 0) {
5396 PyOS_setsig(SIGCHLD, sig_saved);
5397 return posix_error();
5398 }
5399 PyOS_setsig(SIGCHLD, sig_saved);
5400 slave_name = ptsname(master_fd); /* get name of slave */
5401 if (slave_name == NULL)
5402 return posix_error();
5403 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5404 if (slave_fd < 0)
5405 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005406#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005407 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5408 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005409#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005411#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005412#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005413#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005414
Victor Stinner8c62be82010-05-06 00:08:46 +00005415 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005416
Fred Drake8cef4cf2000-06-28 16:40:38 +00005417}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005418#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005419
5420#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005421PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005422"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005423Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5424Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005425To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005426
5427static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005428posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005429{
Victor Stinner8c62be82010-05-06 00:08:46 +00005430 int master_fd = -1, result = 0;
5431 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005432
Victor Stinner8c62be82010-05-06 00:08:46 +00005433 _PyImport_AcquireLock();
5434 pid = forkpty(&master_fd, NULL, NULL, NULL);
5435 if (pid == 0) {
5436 /* child: this clobbers and resets the import lock. */
5437 PyOS_AfterFork();
5438 } else {
5439 /* parent: release the import lock. */
5440 result = _PyImport_ReleaseLock();
5441 }
5442 if (pid == -1)
5443 return posix_error();
5444 if (result < 0) {
5445 /* Don't clobber the OSError if the fork failed. */
5446 PyErr_SetString(PyExc_RuntimeError,
5447 "not holding the import lock");
5448 return NULL;
5449 }
5450 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005451}
5452#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005453
Ross Lagerwall7807c352011-03-17 20:20:30 +02005454
Guido van Rossumad0ee831995-03-01 10:34:45 +00005455#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005456PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005457"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005458Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005459
Barry Warsaw53699e91996-12-10 23:23:01 +00005460static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005461posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005462{
Victor Stinner8c62be82010-05-06 00:08:46 +00005463 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005464}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005465#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005466
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005467
Guido van Rossumad0ee831995-03-01 10:34:45 +00005468#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005469PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005470"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005471Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005472
Barry Warsaw53699e91996-12-10 23:23:01 +00005473static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005474posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005475{
Victor Stinner8c62be82010-05-06 00:08:46 +00005476 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005477}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005478#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005479
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005480
Guido van Rossumad0ee831995-03-01 10:34:45 +00005481#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005482PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005483"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005485
Barry Warsaw53699e91996-12-10 23:23:01 +00005486static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005487posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005488{
Victor Stinner8c62be82010-05-06 00:08:46 +00005489 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005490}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005491#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005492
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005493
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005494PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005495"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005496Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005497
Barry Warsaw53699e91996-12-10 23:23:01 +00005498static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005499posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005500{
Victor Stinner8c62be82010-05-06 00:08:46 +00005501 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005502}
5503
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005504#ifdef HAVE_GETGROUPLIST
5505PyDoc_STRVAR(posix_getgrouplist__doc__,
5506"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5507Returns a list of groups to which a user belongs.\n\n\
5508 user: username to lookup\n\
5509 group: base group id of the user");
5510
5511static PyObject *
5512posix_getgrouplist(PyObject *self, PyObject *args)
5513{
5514#ifdef NGROUPS_MAX
5515#define MAX_GROUPS NGROUPS_MAX
5516#else
5517 /* defined to be 16 on Solaris7, so this should be a small number */
5518#define MAX_GROUPS 64
5519#endif
5520
5521 const char *user;
5522 int i, ngroups;
5523 PyObject *list;
5524#ifdef __APPLE__
5525 int *groups, basegid;
5526#else
5527 gid_t *groups, basegid;
5528#endif
5529 ngroups = MAX_GROUPS;
5530
5531 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5532 return NULL;
5533
5534#ifdef __APPLE__
5535 groups = PyMem_Malloc(ngroups * sizeof(int));
5536#else
5537 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5538#endif
5539 if (groups == NULL)
5540 return PyErr_NoMemory();
5541
5542 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5543 PyMem_Del(groups);
5544 return posix_error();
5545 }
5546
5547 list = PyList_New(ngroups);
5548 if (list == NULL) {
5549 PyMem_Del(groups);
5550 return NULL;
5551 }
5552
5553 for (i = 0; i < ngroups; i++) {
5554 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5555 if (o == NULL) {
5556 Py_DECREF(list);
5557 PyMem_Del(groups);
5558 return NULL;
5559 }
5560 PyList_SET_ITEM(list, i, o);
5561 }
5562
5563 PyMem_Del(groups);
5564
5565 return list;
5566}
5567#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005568
Fred Drakec9680921999-12-13 16:37:25 +00005569#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005570PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005571"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005572Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005573
5574static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005575posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005576{
5577 PyObject *result = NULL;
5578
Fred Drakec9680921999-12-13 16:37:25 +00005579#ifdef NGROUPS_MAX
5580#define MAX_GROUPS NGROUPS_MAX
5581#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005582 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005583#define MAX_GROUPS 64
5584#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005585 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005586
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005587 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005588 * This is a helper variable to store the intermediate result when
5589 * that happens.
5590 *
5591 * To keep the code readable the OSX behaviour is unconditional,
5592 * according to the POSIX spec this should be safe on all unix-y
5593 * systems.
5594 */
5595 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005596 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005597
Victor Stinner8c62be82010-05-06 00:08:46 +00005598 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005599 if (n < 0) {
5600 if (errno == EINVAL) {
5601 n = getgroups(0, NULL);
5602 if (n == -1) {
5603 return posix_error();
5604 }
5605 if (n == 0) {
5606 /* Avoid malloc(0) */
5607 alt_grouplist = grouplist;
5608 } else {
5609 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5610 if (alt_grouplist == NULL) {
5611 errno = EINVAL;
5612 return posix_error();
5613 }
5614 n = getgroups(n, alt_grouplist);
5615 if (n == -1) {
5616 PyMem_Free(alt_grouplist);
5617 return posix_error();
5618 }
5619 }
5620 } else {
5621 return posix_error();
5622 }
5623 }
5624 result = PyList_New(n);
5625 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005626 int i;
5627 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005628 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005629 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005630 Py_DECREF(result);
5631 result = NULL;
5632 break;
Fred Drakec9680921999-12-13 16:37:25 +00005633 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005634 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005635 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005636 }
5637
5638 if (alt_grouplist != grouplist) {
5639 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005640 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005641
Fred Drakec9680921999-12-13 16:37:25 +00005642 return result;
5643}
5644#endif
5645
Antoine Pitroub7572f02009-12-02 20:46:48 +00005646#ifdef HAVE_INITGROUPS
5647PyDoc_STRVAR(posix_initgroups__doc__,
5648"initgroups(username, gid) -> None\n\n\
5649Call the system initgroups() to initialize the group access list with all of\n\
5650the groups of which the specified username is a member, plus the specified\n\
5651group id.");
5652
5653static PyObject *
5654posix_initgroups(PyObject *self, PyObject *args)
5655{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005656 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005657 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005658 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005659 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005660
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005661 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5662 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005663 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005664 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005665
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005666 res = initgroups(username, (gid_t) gid);
5667 Py_DECREF(oname);
5668 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005669 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005670
Victor Stinner8c62be82010-05-06 00:08:46 +00005671 Py_INCREF(Py_None);
5672 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005673}
5674#endif
5675
Martin v. Löwis606edc12002-06-13 21:09:11 +00005676#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005677PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005678"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005679Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005680
5681static PyObject *
5682posix_getpgid(PyObject *self, PyObject *args)
5683{
Victor Stinner8c62be82010-05-06 00:08:46 +00005684 pid_t pid, pgid;
5685 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5686 return NULL;
5687 pgid = getpgid(pid);
5688 if (pgid < 0)
5689 return posix_error();
5690 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005691}
5692#endif /* HAVE_GETPGID */
5693
5694
Guido van Rossumb6775db1994-08-01 11:34:53 +00005695#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005696PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005697"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005698Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005699
Barry Warsaw53699e91996-12-10 23:23:01 +00005700static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005701posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005702{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005703#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005704 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005705#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005706 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005707#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005708}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005709#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005710
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005711
Guido van Rossumb6775db1994-08-01 11:34:53 +00005712#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005713PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005714"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005715Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005716
Barry Warsaw53699e91996-12-10 23:23:01 +00005717static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005718posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005719{
Guido van Rossum64933891994-10-20 21:56:42 +00005720#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005721 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005722#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005723 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005724#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005725 return posix_error();
5726 Py_INCREF(Py_None);
5727 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005728}
5729
Guido van Rossumb6775db1994-08-01 11:34:53 +00005730#endif /* HAVE_SETPGRP */
5731
Guido van Rossumad0ee831995-03-01 10:34:45 +00005732#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005733
5734#ifdef MS_WINDOWS
5735#include <tlhelp32.h>
5736
5737static PyObject*
5738win32_getppid()
5739{
5740 HANDLE snapshot;
5741 pid_t mypid;
5742 PyObject* result = NULL;
5743 BOOL have_record;
5744 PROCESSENTRY32 pe;
5745
5746 mypid = getpid(); /* This function never fails */
5747
5748 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5749 if (snapshot == INVALID_HANDLE_VALUE)
5750 return PyErr_SetFromWindowsErr(GetLastError());
5751
5752 pe.dwSize = sizeof(pe);
5753 have_record = Process32First(snapshot, &pe);
5754 while (have_record) {
5755 if (mypid == (pid_t)pe.th32ProcessID) {
5756 /* We could cache the ulong value in a static variable. */
5757 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5758 break;
5759 }
5760
5761 have_record = Process32Next(snapshot, &pe);
5762 }
5763
5764 /* If our loop exits and our pid was not found (result will be NULL)
5765 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5766 * error anyway, so let's raise it. */
5767 if (!result)
5768 result = PyErr_SetFromWindowsErr(GetLastError());
5769
5770 CloseHandle(snapshot);
5771
5772 return result;
5773}
5774#endif /*MS_WINDOWS*/
5775
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005776PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005777"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005778Return the parent's process id. If the parent process has already exited,\n\
5779Windows machines will still return its id; others systems will return the id\n\
5780of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005781
Barry Warsaw53699e91996-12-10 23:23:01 +00005782static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005783posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005784{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005785#ifdef MS_WINDOWS
5786 return win32_getppid();
5787#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005788 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005789#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005790}
5791#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005792
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005793
Fred Drake12c6e2d1999-12-14 21:25:03 +00005794#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005795PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005796"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005797Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005798
5799static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005800posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005801{
Victor Stinner8c62be82010-05-06 00:08:46 +00005802 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005803#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005804 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005805 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005806
5807 if (GetUserNameW(user_name, &num_chars)) {
5808 /* num_chars is the number of unicode chars plus null terminator */
5809 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005810 }
5811 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005812 result = PyErr_SetFromWindowsErr(GetLastError());
5813#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005814 char *name;
5815 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005816
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 errno = 0;
5818 name = getlogin();
5819 if (name == NULL) {
5820 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005821 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005822 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005823 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005824 }
5825 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005826 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005827 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005828#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005829 return result;
5830}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005831#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005832
Guido van Rossumad0ee831995-03-01 10:34:45 +00005833#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005834PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005835"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005836Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005837
Barry Warsaw53699e91996-12-10 23:23:01 +00005838static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005839posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005840{
Victor Stinner8c62be82010-05-06 00:08:46 +00005841 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005842}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005843#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005844
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005845
Guido van Rossumad0ee831995-03-01 10:34:45 +00005846#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005847PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005848"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005849Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005850
Barry Warsaw53699e91996-12-10 23:23:01 +00005851static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005852posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005853{
Victor Stinner8c62be82010-05-06 00:08:46 +00005854 pid_t pid;
5855 int sig;
5856 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5857 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005858#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005859 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
5860 APIRET rc;
5861 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005862 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005863
5864 } else if (sig == XCPT_SIGNAL_KILLPROC) {
5865 APIRET rc;
5866 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005867 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005868
5869 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005870 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005871#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005872 if (kill(pid, sig) == -1)
5873 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005874#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005875 Py_INCREF(Py_None);
5876 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005877}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005878#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005879
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005880#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005881PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005882"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005883Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005884
5885static PyObject *
5886posix_killpg(PyObject *self, PyObject *args)
5887{
Victor Stinner8c62be82010-05-06 00:08:46 +00005888 int sig;
5889 pid_t pgid;
5890 /* XXX some man pages make the `pgid` parameter an int, others
5891 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5892 take the same type. Moreover, pid_t is always at least as wide as
5893 int (else compilation of this module fails), which is safe. */
5894 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5895 return NULL;
5896 if (killpg(pgid, sig) == -1)
5897 return posix_error();
5898 Py_INCREF(Py_None);
5899 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005900}
5901#endif
5902
Brian Curtineb24d742010-04-12 17:16:38 +00005903#ifdef MS_WINDOWS
5904PyDoc_STRVAR(win32_kill__doc__,
5905"kill(pid, sig)\n\n\
5906Kill a process with a signal.");
5907
5908static PyObject *
5909win32_kill(PyObject *self, PyObject *args)
5910{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005911 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 DWORD pid, sig, err;
5913 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005914
Victor Stinner8c62be82010-05-06 00:08:46 +00005915 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5916 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005917
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 /* Console processes which share a common console can be sent CTRL+C or
5919 CTRL+BREAK events, provided they handle said events. */
5920 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
5921 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
5922 err = GetLastError();
5923 PyErr_SetFromWindowsErr(err);
5924 }
5925 else
5926 Py_RETURN_NONE;
5927 }
Brian Curtineb24d742010-04-12 17:16:38 +00005928
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
5930 attempt to open and terminate the process. */
5931 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
5932 if (handle == NULL) {
5933 err = GetLastError();
5934 return PyErr_SetFromWindowsErr(err);
5935 }
Brian Curtineb24d742010-04-12 17:16:38 +00005936
Victor Stinner8c62be82010-05-06 00:08:46 +00005937 if (TerminateProcess(handle, sig) == 0) {
5938 err = GetLastError();
5939 result = PyErr_SetFromWindowsErr(err);
5940 } else {
5941 Py_INCREF(Py_None);
5942 result = Py_None;
5943 }
Brian Curtineb24d742010-04-12 17:16:38 +00005944
Victor Stinner8c62be82010-05-06 00:08:46 +00005945 CloseHandle(handle);
5946 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00005947}
5948#endif /* MS_WINDOWS */
5949
Guido van Rossumc0125471996-06-28 18:55:32 +00005950#ifdef HAVE_PLOCK
5951
5952#ifdef HAVE_SYS_LOCK_H
5953#include <sys/lock.h>
5954#endif
5955
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005956PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005957"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005958Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005959
Barry Warsaw53699e91996-12-10 23:23:01 +00005960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005961posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00005962{
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 int op;
5964 if (!PyArg_ParseTuple(args, "i:plock", &op))
5965 return NULL;
5966 if (plock(op) == -1)
5967 return posix_error();
5968 Py_INCREF(Py_None);
5969 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00005970}
5971#endif
5972
Guido van Rossumb6775db1994-08-01 11:34:53 +00005973#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005974PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005975"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005976Set the current process's user id.");
5977
Barry Warsaw53699e91996-12-10 23:23:01 +00005978static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005979posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005980{
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 long uid_arg;
5982 uid_t uid;
5983 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5984 return NULL;
5985 uid = uid_arg;
5986 if (uid != uid_arg) {
5987 PyErr_SetString(PyExc_OverflowError, "user id too big");
5988 return NULL;
5989 }
5990 if (setuid(uid) < 0)
5991 return posix_error();
5992 Py_INCREF(Py_None);
5993 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005994}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005995#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005996
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005997
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005998#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005999PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006000"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006001Set the current process's effective user id.");
6002
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006003static PyObject *
6004posix_seteuid (PyObject *self, PyObject *args)
6005{
Victor Stinner8c62be82010-05-06 00:08:46 +00006006 long euid_arg;
6007 uid_t euid;
6008 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6009 return NULL;
6010 euid = euid_arg;
6011 if (euid != euid_arg) {
6012 PyErr_SetString(PyExc_OverflowError, "user id too big");
6013 return NULL;
6014 }
6015 if (seteuid(euid) < 0) {
6016 return posix_error();
6017 } else {
6018 Py_INCREF(Py_None);
6019 return Py_None;
6020 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006021}
6022#endif /* HAVE_SETEUID */
6023
6024#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006025PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006026"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006027Set the current process's effective group id.");
6028
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006029static PyObject *
6030posix_setegid (PyObject *self, PyObject *args)
6031{
Victor Stinner8c62be82010-05-06 00:08:46 +00006032 long egid_arg;
6033 gid_t egid;
6034 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6035 return NULL;
6036 egid = egid_arg;
6037 if (egid != egid_arg) {
6038 PyErr_SetString(PyExc_OverflowError, "group id too big");
6039 return NULL;
6040 }
6041 if (setegid(egid) < 0) {
6042 return posix_error();
6043 } else {
6044 Py_INCREF(Py_None);
6045 return Py_None;
6046 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006047}
6048#endif /* HAVE_SETEGID */
6049
6050#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006051PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006052"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006053Set the current process's real and effective user ids.");
6054
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006055static PyObject *
6056posix_setreuid (PyObject *self, PyObject *args)
6057{
Victor Stinner8c62be82010-05-06 00:08:46 +00006058 long ruid_arg, euid_arg;
6059 uid_t ruid, euid;
6060 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6061 return NULL;
6062 if (ruid_arg == -1)
6063 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6064 else
6065 ruid = ruid_arg; /* otherwise, assign from our long */
6066 if (euid_arg == -1)
6067 euid = (uid_t)-1;
6068 else
6069 euid = euid_arg;
6070 if ((euid_arg != -1 && euid != euid_arg) ||
6071 (ruid_arg != -1 && ruid != ruid_arg)) {
6072 PyErr_SetString(PyExc_OverflowError, "user id too big");
6073 return NULL;
6074 }
6075 if (setreuid(ruid, euid) < 0) {
6076 return posix_error();
6077 } else {
6078 Py_INCREF(Py_None);
6079 return Py_None;
6080 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006081}
6082#endif /* HAVE_SETREUID */
6083
6084#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006085PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006086"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006087Set the current process's real and effective group ids.");
6088
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006089static PyObject *
6090posix_setregid (PyObject *self, PyObject *args)
6091{
Victor Stinner8c62be82010-05-06 00:08:46 +00006092 long rgid_arg, egid_arg;
6093 gid_t rgid, egid;
6094 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6095 return NULL;
6096 if (rgid_arg == -1)
6097 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6098 else
6099 rgid = rgid_arg; /* otherwise, assign from our long */
6100 if (egid_arg == -1)
6101 egid = (gid_t)-1;
6102 else
6103 egid = egid_arg;
6104 if ((egid_arg != -1 && egid != egid_arg) ||
6105 (rgid_arg != -1 && rgid != rgid_arg)) {
6106 PyErr_SetString(PyExc_OverflowError, "group id too big");
6107 return NULL;
6108 }
6109 if (setregid(rgid, egid) < 0) {
6110 return posix_error();
6111 } else {
6112 Py_INCREF(Py_None);
6113 return Py_None;
6114 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006115}
6116#endif /* HAVE_SETREGID */
6117
Guido van Rossumb6775db1994-08-01 11:34:53 +00006118#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006119PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006120"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006122
Barry Warsaw53699e91996-12-10 23:23:01 +00006123static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006124posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006125{
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 long gid_arg;
6127 gid_t gid;
6128 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6129 return NULL;
6130 gid = gid_arg;
6131 if (gid != gid_arg) {
6132 PyErr_SetString(PyExc_OverflowError, "group id too big");
6133 return NULL;
6134 }
6135 if (setgid(gid) < 0)
6136 return posix_error();
6137 Py_INCREF(Py_None);
6138 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006139}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006140#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006141
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006142#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006143PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006144"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006145Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006146
6147static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006148posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006149{
Victor Stinner8c62be82010-05-06 00:08:46 +00006150 int i, len;
6151 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006152
Victor Stinner8c62be82010-05-06 00:08:46 +00006153 if (!PySequence_Check(groups)) {
6154 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6155 return NULL;
6156 }
6157 len = PySequence_Size(groups);
6158 if (len > MAX_GROUPS) {
6159 PyErr_SetString(PyExc_ValueError, "too many groups");
6160 return NULL;
6161 }
6162 for(i = 0; i < len; i++) {
6163 PyObject *elem;
6164 elem = PySequence_GetItem(groups, i);
6165 if (!elem)
6166 return NULL;
6167 if (!PyLong_Check(elem)) {
6168 PyErr_SetString(PyExc_TypeError,
6169 "groups must be integers");
6170 Py_DECREF(elem);
6171 return NULL;
6172 } else {
6173 unsigned long x = PyLong_AsUnsignedLong(elem);
6174 if (PyErr_Occurred()) {
6175 PyErr_SetString(PyExc_TypeError,
6176 "group id too big");
6177 Py_DECREF(elem);
6178 return NULL;
6179 }
6180 grouplist[i] = x;
6181 /* read back the value to see if it fitted in gid_t */
6182 if (grouplist[i] != x) {
6183 PyErr_SetString(PyExc_TypeError,
6184 "group id too big");
6185 Py_DECREF(elem);
6186 return NULL;
6187 }
6188 }
6189 Py_DECREF(elem);
6190 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006191
Victor Stinner8c62be82010-05-06 00:08:46 +00006192 if (setgroups(len, grouplist) < 0)
6193 return posix_error();
6194 Py_INCREF(Py_None);
6195 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006196}
6197#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006198
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006199#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6200static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006201wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006202{
Victor Stinner8c62be82010-05-06 00:08:46 +00006203 PyObject *result;
6204 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006205 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006206
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 if (pid == -1)
6208 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006209
Victor Stinner8c62be82010-05-06 00:08:46 +00006210 if (struct_rusage == NULL) {
6211 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6212 if (m == NULL)
6213 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006214 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 Py_DECREF(m);
6216 if (struct_rusage == NULL)
6217 return NULL;
6218 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006219
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6221 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6222 if (!result)
6223 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006224
6225#ifndef doubletime
6226#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6227#endif
6228
Victor Stinner8c62be82010-05-06 00:08:46 +00006229 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006230 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006231 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006232 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006233#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6235 SET_INT(result, 2, ru->ru_maxrss);
6236 SET_INT(result, 3, ru->ru_ixrss);
6237 SET_INT(result, 4, ru->ru_idrss);
6238 SET_INT(result, 5, ru->ru_isrss);
6239 SET_INT(result, 6, ru->ru_minflt);
6240 SET_INT(result, 7, ru->ru_majflt);
6241 SET_INT(result, 8, ru->ru_nswap);
6242 SET_INT(result, 9, ru->ru_inblock);
6243 SET_INT(result, 10, ru->ru_oublock);
6244 SET_INT(result, 11, ru->ru_msgsnd);
6245 SET_INT(result, 12, ru->ru_msgrcv);
6246 SET_INT(result, 13, ru->ru_nsignals);
6247 SET_INT(result, 14, ru->ru_nvcsw);
6248 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006249#undef SET_INT
6250
Victor Stinner8c62be82010-05-06 00:08:46 +00006251 if (PyErr_Occurred()) {
6252 Py_DECREF(result);
6253 return NULL;
6254 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006255
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006257}
6258#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6259
6260#ifdef HAVE_WAIT3
6261PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006262"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006263Wait for completion of a child process.");
6264
6265static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006266posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006267{
Victor Stinner8c62be82010-05-06 00:08:46 +00006268 pid_t pid;
6269 int options;
6270 struct rusage ru;
6271 WAIT_TYPE status;
6272 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006273
Victor Stinner4195b5c2012-02-08 23:03:19 +01006274 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006276
Victor Stinner8c62be82010-05-06 00:08:46 +00006277 Py_BEGIN_ALLOW_THREADS
6278 pid = wait3(&status, options, &ru);
6279 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006280
Victor Stinner4195b5c2012-02-08 23:03:19 +01006281 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006282}
6283#endif /* HAVE_WAIT3 */
6284
6285#ifdef HAVE_WAIT4
6286PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006287"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006288Wait for completion of a given child process.");
6289
6290static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006291posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006292{
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 pid_t pid;
6294 int options;
6295 struct rusage ru;
6296 WAIT_TYPE status;
6297 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006298
Victor Stinner4195b5c2012-02-08 23:03:19 +01006299 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006301
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 Py_BEGIN_ALLOW_THREADS
6303 pid = wait4(pid, &status, options, &ru);
6304 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006305
Victor Stinner4195b5c2012-02-08 23:03:19 +01006306 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006307}
6308#endif /* HAVE_WAIT4 */
6309
Ross Lagerwall7807c352011-03-17 20:20:30 +02006310#if defined(HAVE_WAITID) && !defined(__APPLE__)
6311PyDoc_STRVAR(posix_waitid__doc__,
6312"waitid(idtype, id, options) -> waitid_result\n\n\
6313Wait for the completion of one or more child processes.\n\n\
6314idtype can be P_PID, P_PGID or P_ALL.\n\
6315id specifies the pid to wait on.\n\
6316options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6317or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6318Returns either waitid_result or None if WNOHANG is specified and there are\n\
6319no children in a waitable state.");
6320
6321static PyObject *
6322posix_waitid(PyObject *self, PyObject *args)
6323{
6324 PyObject *result;
6325 idtype_t idtype;
6326 id_t id;
6327 int options, res;
6328 siginfo_t si;
6329 si.si_pid = 0;
6330 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6331 return NULL;
6332 Py_BEGIN_ALLOW_THREADS
6333 res = waitid(idtype, id, &si, options);
6334 Py_END_ALLOW_THREADS
6335 if (res == -1)
6336 return posix_error();
6337
6338 if (si.si_pid == 0)
6339 Py_RETURN_NONE;
6340
6341 result = PyStructSequence_New(&WaitidResultType);
6342 if (!result)
6343 return NULL;
6344
6345 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6346 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6347 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6348 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6349 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6350 if (PyErr_Occurred()) {
6351 Py_DECREF(result);
6352 return NULL;
6353 }
6354
6355 return result;
6356}
6357#endif
6358
Guido van Rossumb6775db1994-08-01 11:34:53 +00006359#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006360PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006361"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006362Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006363
Barry Warsaw53699e91996-12-10 23:23:01 +00006364static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006365posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006366{
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 pid_t pid;
6368 int options;
6369 WAIT_TYPE status;
6370 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006371
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6373 return NULL;
6374 Py_BEGIN_ALLOW_THREADS
6375 pid = waitpid(pid, &status, options);
6376 Py_END_ALLOW_THREADS
6377 if (pid == -1)
6378 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006379
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006381}
6382
Tim Petersab034fa2002-02-01 11:27:43 +00006383#elif defined(HAVE_CWAIT)
6384
6385/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006386PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006387"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006388"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006389
6390static PyObject *
6391posix_waitpid(PyObject *self, PyObject *args)
6392{
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 Py_intptr_t pid;
6394 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006395
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6397 return NULL;
6398 Py_BEGIN_ALLOW_THREADS
6399 pid = _cwait(&status, pid, options);
6400 Py_END_ALLOW_THREADS
6401 if (pid == -1)
6402 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006403
Victor Stinner8c62be82010-05-06 00:08:46 +00006404 /* shift the status left a byte so this is more like the POSIX waitpid */
6405 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006406}
6407#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006408
Guido van Rossumad0ee831995-03-01 10:34:45 +00006409#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006410PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006411"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006412Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006413
Barry Warsaw53699e91996-12-10 23:23:01 +00006414static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006415posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006416{
Victor Stinner8c62be82010-05-06 00:08:46 +00006417 pid_t pid;
6418 WAIT_TYPE status;
6419 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006420
Victor Stinner8c62be82010-05-06 00:08:46 +00006421 Py_BEGIN_ALLOW_THREADS
6422 pid = wait(&status);
6423 Py_END_ALLOW_THREADS
6424 if (pid == -1)
6425 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006426
Victor Stinner8c62be82010-05-06 00:08:46 +00006427 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006428}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006429#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006430
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006431
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006432PyDoc_STRVAR(posix_lstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006433"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006434Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006435
Barry Warsaw53699e91996-12-10 23:23:01 +00006436static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006437posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006438{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006439#ifdef HAVE_LSTAT
Victor Stinner4195b5c2012-02-08 23:03:19 +01006440 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006441#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006442#ifdef MS_WINDOWS
Victor Stinner4195b5c2012-02-08 23:03:19 +01006443 return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00006444 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006445#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01006446 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006447#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006448#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006449}
6450
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006451
Guido van Rossumb6775db1994-08-01 11:34:53 +00006452#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006453PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006454"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006455Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006456
Barry Warsaw53699e91996-12-10 23:23:01 +00006457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006458posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006459{
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 PyObject* v;
6461 char buf[MAXPATHLEN];
6462 PyObject *opath;
6463 char *path;
6464 int n;
6465 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006466
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 if (!PyArg_ParseTuple(args, "O&:readlink",
6468 PyUnicode_FSConverter, &opath))
6469 return NULL;
6470 path = PyBytes_AsString(opath);
6471 v = PySequence_GetItem(args, 0);
6472 if (v == NULL) {
6473 Py_DECREF(opath);
6474 return NULL;
6475 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00006476
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 if (PyUnicode_Check(v)) {
6478 arg_is_unicode = 1;
6479 }
6480 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006481
Victor Stinner8c62be82010-05-06 00:08:46 +00006482 Py_BEGIN_ALLOW_THREADS
6483 n = readlink(path, buf, (int) sizeof buf);
6484 Py_END_ALLOW_THREADS
6485 if (n < 0)
6486 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006487
Victor Stinner8c62be82010-05-06 00:08:46 +00006488 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00006489 if (arg_is_unicode)
6490 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
6491 else
6492 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006493}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006494#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006495
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006496
Brian Curtin52173d42010-12-02 18:29:18 +00006497#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006498PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006499"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006500Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006501
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006503posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006504{
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006506}
6507#endif /* HAVE_SYMLINK */
6508
Brian Curtind40e6f72010-07-08 21:39:08 +00006509#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6510
6511PyDoc_STRVAR(win_readlink__doc__,
6512"readlink(path) -> path\n\n\
6513Return a string representing the path to which the symbolic link points.");
6514
Brian Curtind40e6f72010-07-08 21:39:08 +00006515/* Windows readlink implementation */
6516static PyObject *
6517win_readlink(PyObject *self, PyObject *args)
6518{
6519 wchar_t *path;
6520 DWORD n_bytes_returned;
6521 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006522 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00006523 HANDLE reparse_point_handle;
6524
6525 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6526 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6527 wchar_t *print_name;
6528
6529 if (!PyArg_ParseTuple(args,
Victor Stinnereb5657a2011-09-30 01:44:27 +02006530 "U:readlink",
6531 &po))
6532 return NULL;
6533 path = PyUnicode_AsUnicode(po);
6534 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006535 return NULL;
6536
6537 /* First get a handle to the reparse point */
6538 Py_BEGIN_ALLOW_THREADS
6539 reparse_point_handle = CreateFileW(
6540 path,
6541 0,
6542 0,
6543 0,
6544 OPEN_EXISTING,
6545 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6546 0);
6547 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006548
Brian Curtind40e6f72010-07-08 21:39:08 +00006549 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006550 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006551
Brian Curtind40e6f72010-07-08 21:39:08 +00006552 Py_BEGIN_ALLOW_THREADS
6553 /* New call DeviceIoControl to read the reparse point */
6554 io_result = DeviceIoControl(
6555 reparse_point_handle,
6556 FSCTL_GET_REPARSE_POINT,
6557 0, 0, /* in buffer */
6558 target_buffer, sizeof(target_buffer),
6559 &n_bytes_returned,
6560 0 /* we're not using OVERLAPPED_IO */
6561 );
6562 CloseHandle(reparse_point_handle);
6563 Py_END_ALLOW_THREADS
6564
6565 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006566 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006567
6568 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6569 {
6570 PyErr_SetString(PyExc_ValueError,
6571 "not a symbolic link");
6572 return NULL;
6573 }
Brian Curtin74e45612010-07-09 15:58:59 +00006574 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6575 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6576
6577 result = PyUnicode_FromWideChar(print_name,
6578 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006579 return result;
6580}
6581
6582#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6583
Brian Curtin52173d42010-12-02 18:29:18 +00006584#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00006585
6586/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6587static int has_CreateSymbolicLinkW = 0;
6588static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
6589static int
6590check_CreateSymbolicLinkW()
6591{
6592 HINSTANCE hKernel32;
6593 /* only recheck */
6594 if (has_CreateSymbolicLinkW)
6595 return has_CreateSymbolicLinkW;
Martin v. Löwis50590f12012-01-14 17:54:09 +01006596 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00006597 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6598 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00006599 if (Py_CreateSymbolicLinkW)
6600 has_CreateSymbolicLinkW = 1;
6601 return has_CreateSymbolicLinkW;
6602}
6603
6604PyDoc_STRVAR(win_symlink__doc__,
6605"symlink(src, dst, target_is_directory=False)\n\n\
6606Create a symbolic link pointing to src named dst.\n\
6607target_is_directory is required if the target is to be interpreted as\n\
6608a directory.\n\
6609This function requires Windows 6.0 or greater, and raises a\n\
6610NotImplementedError otherwise.");
6611
6612static PyObject *
6613win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
6614{
6615 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006616 PyObject *osrc, *odest;
6617 PyObject *usrc = NULL, *udest = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006618 wchar_t *wsrc, *wdest;
Brian Curtind40e6f72010-07-08 21:39:08 +00006619 int target_is_directory = 0;
6620 DWORD res;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006621
Brian Curtind40e6f72010-07-08 21:39:08 +00006622 if (!check_CreateSymbolicLinkW())
6623 {
6624 /* raise NotImplementedError */
6625 return PyErr_Format(PyExc_NotImplementedError,
6626 "CreateSymbolicLinkW not found");
6627 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006628 if (!PyArg_ParseTupleAndKeywords(
6629 args, kwargs, "OO|i:symlink", kwlist,
6630 &osrc, &odest, &target_is_directory))
Brian Curtind40e6f72010-07-08 21:39:08 +00006631 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00006632
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006633 usrc = win32_decode_filename(osrc);
6634 if (!usrc)
6635 return NULL;
6636 udest = win32_decode_filename(odest);
6637 if (!udest)
6638 goto error;
6639
Brian Curtin3b4499c2010-12-28 14:31:47 +00006640 if (win32_can_symlink == 0)
6641 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
6642
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006643 wsrc = PyUnicode_AsUnicode(usrc);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006644 if (wsrc == NULL)
6645 goto error;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006646 wdest = PyUnicode_AsUnicode(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006647 if (wsrc == NULL)
6648 goto error;
6649
Brian Curtind40e6f72010-07-08 21:39:08 +00006650 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006651 res = Py_CreateSymbolicLinkW(wdest, wsrc, target_is_directory);
Brian Curtind40e6f72010-07-08 21:39:08 +00006652 Py_END_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006653
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006654 Py_DECREF(usrc);
6655 Py_DECREF(udest);
Brian Curtind40e6f72010-07-08 21:39:08 +00006656 if (!res)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006657 return win32_error_object("symlink", osrc);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006658
Brian Curtind40e6f72010-07-08 21:39:08 +00006659 Py_INCREF(Py_None);
6660 return Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006661
6662error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006663 Py_XDECREF(usrc);
6664 Py_XDECREF(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006665 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00006666}
Brian Curtin52173d42010-12-02 18:29:18 +00006667#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006668
6669#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006670#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6671static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006672system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006673{
6674 ULONG value = 0;
6675
6676 Py_BEGIN_ALLOW_THREADS
6677 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6678 Py_END_ALLOW_THREADS
6679
6680 return value;
6681}
6682
6683static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006684posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006685{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006686 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00006687 return Py_BuildValue("ddddd",
6688 (double)0 /* t.tms_utime / HZ */,
6689 (double)0 /* t.tms_stime / HZ */,
6690 (double)0 /* t.tms_cutime / HZ */,
6691 (double)0 /* t.tms_cstime / HZ */,
6692 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006693}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006694#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00006695#define NEED_TICKS_PER_SECOND
6696static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006697static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006698posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006699{
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 struct tms t;
6701 clock_t c;
6702 errno = 0;
6703 c = times(&t);
6704 if (c == (clock_t) -1)
6705 return posix_error();
6706 return Py_BuildValue("ddddd",
6707 (double)t.tms_utime / ticks_per_second,
6708 (double)t.tms_stime / ticks_per_second,
6709 (double)t.tms_cutime / ticks_per_second,
6710 (double)t.tms_cstime / ticks_per_second,
6711 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006712}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006713#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006714#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006715
6716
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006717#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006718#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006719static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006720posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006721{
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 FILETIME create, exit, kernel, user;
6723 HANDLE hProc;
6724 hProc = GetCurrentProcess();
6725 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6726 /* The fields of a FILETIME structure are the hi and lo part
6727 of a 64-bit value expressed in 100 nanosecond units.
6728 1e7 is one second in such units; 1e-7 the inverse.
6729 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6730 */
6731 return Py_BuildValue(
6732 "ddddd",
6733 (double)(user.dwHighDateTime*429.4967296 +
6734 user.dwLowDateTime*1e-7),
6735 (double)(kernel.dwHighDateTime*429.4967296 +
6736 kernel.dwLowDateTime*1e-7),
6737 (double)0,
6738 (double)0,
6739 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006740}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006741#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006742
6743#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006744PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006745"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006746Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006747#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006749
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006750#ifdef HAVE_GETSID
6751PyDoc_STRVAR(posix_getsid__doc__,
6752"getsid(pid) -> sid\n\n\
6753Call the system call getsid().");
6754
6755static PyObject *
6756posix_getsid(PyObject *self, PyObject *args)
6757{
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 pid_t pid;
6759 int sid;
6760 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6761 return NULL;
6762 sid = getsid(pid);
6763 if (sid < 0)
6764 return posix_error();
6765 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006766}
6767#endif /* HAVE_GETSID */
6768
6769
Guido van Rossumb6775db1994-08-01 11:34:53 +00006770#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006771PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006772"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006773Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006774
Barry Warsaw53699e91996-12-10 23:23:01 +00006775static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006776posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006777{
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 if (setsid() < 0)
6779 return posix_error();
6780 Py_INCREF(Py_None);
6781 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006782}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006783#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006784
Guido van Rossumb6775db1994-08-01 11:34:53 +00006785#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006786PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006787"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006788Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006789
Barry Warsaw53699e91996-12-10 23:23:01 +00006790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006791posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006792{
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 pid_t pid;
6794 int pgrp;
6795 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6796 return NULL;
6797 if (setpgid(pid, pgrp) < 0)
6798 return posix_error();
6799 Py_INCREF(Py_None);
6800 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006801}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006802#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006803
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006804
Guido van Rossumb6775db1994-08-01 11:34:53 +00006805#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006806PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006807"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006808Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006809
Barry Warsaw53699e91996-12-10 23:23:01 +00006810static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006811posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006812{
Victor Stinner8c62be82010-05-06 00:08:46 +00006813 int fd;
6814 pid_t pgid;
6815 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6816 return NULL;
6817 pgid = tcgetpgrp(fd);
6818 if (pgid < 0)
6819 return posix_error();
6820 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006821}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006822#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006823
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006824
Guido van Rossumb6775db1994-08-01 11:34:53 +00006825#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006826PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006827"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006828Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006829
Barry Warsaw53699e91996-12-10 23:23:01 +00006830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006831posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006832{
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 int fd;
6834 pid_t pgid;
6835 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6836 return NULL;
6837 if (tcsetpgrp(fd, pgid) < 0)
6838 return posix_error();
6839 Py_INCREF(Py_None);
6840 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006841}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006842#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006843
Guido van Rossum687dd131993-05-17 08:34:16 +00006844/* Functions acting on file descriptors */
6845
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006846PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006847"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006848Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006849
Barry Warsaw53699e91996-12-10 23:23:01 +00006850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006851posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006852{
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 PyObject *ofile;
6854 char *file;
6855 int flag;
6856 int mode = 0777;
6857 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006858
6859#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006860 PyObject *po;
Victor Stinner26de69d2011-06-17 15:15:38 +02006861 if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02006862 wchar_t *wpath = PyUnicode_AsUnicode(po);
6863 if (wpath == NULL)
6864 return NULL;
6865
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006867 fd = _wopen(wpath, flag, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 Py_END_ALLOW_THREADS
6869 if (fd < 0)
6870 return posix_error();
6871 return PyLong_FromLong((long)fd);
6872 }
6873 /* Drop the argument parsing error as narrow strings
6874 are also valid. */
6875 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006876#endif
6877
Victor Stinner26de69d2011-06-17 15:15:38 +02006878 if (!PyArg_ParseTuple(args, "O&i|i:open",
Victor Stinner8c62be82010-05-06 00:08:46 +00006879 PyUnicode_FSConverter, &ofile,
6880 &flag, &mode))
6881 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006882#ifdef MS_WINDOWS
6883 if (win32_warn_bytes_api()) {
6884 Py_DECREF(ofile);
6885 return NULL;
6886 }
6887#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006888 file = PyBytes_AsString(ofile);
6889 Py_BEGIN_ALLOW_THREADS
6890 fd = open(file, flag, mode);
6891 Py_END_ALLOW_THREADS
6892 if (fd < 0)
6893 return posix_error_with_allocated_filename(ofile);
6894 Py_DECREF(ofile);
6895 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006896}
6897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006898
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006899PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006900"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006901Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006902
Barry Warsaw53699e91996-12-10 23:23:01 +00006903static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006904posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006905{
Victor Stinner8c62be82010-05-06 00:08:46 +00006906 int fd, res;
6907 if (!PyArg_ParseTuple(args, "i:close", &fd))
6908 return NULL;
6909 if (!_PyVerify_fd(fd))
6910 return posix_error();
6911 Py_BEGIN_ALLOW_THREADS
6912 res = close(fd);
6913 Py_END_ALLOW_THREADS
6914 if (res < 0)
6915 return posix_error();
6916 Py_INCREF(Py_None);
6917 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006918}
6919
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006920
Victor Stinner8c62be82010-05-06 00:08:46 +00006921PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00006922"closerange(fd_low, fd_high)\n\n\
6923Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6924
6925static PyObject *
6926posix_closerange(PyObject *self, PyObject *args)
6927{
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 int fd_from, fd_to, i;
6929 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6930 return NULL;
6931 Py_BEGIN_ALLOW_THREADS
6932 for (i = fd_from; i < fd_to; i++)
6933 if (_PyVerify_fd(i))
6934 close(i);
6935 Py_END_ALLOW_THREADS
6936 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00006937}
6938
6939
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006940PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006941"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006942Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006943
Barry Warsaw53699e91996-12-10 23:23:01 +00006944static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006945posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006946{
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 int fd;
6948 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6949 return NULL;
6950 if (!_PyVerify_fd(fd))
6951 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 if (fd < 0)
6954 return posix_error();
6955 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006956}
6957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006958
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006959PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006960"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006961Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006962
Barry Warsaw53699e91996-12-10 23:23:01 +00006963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006964posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006965{
Victor Stinner8c62be82010-05-06 00:08:46 +00006966 int fd, fd2, res;
6967 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6968 return NULL;
6969 if (!_PyVerify_fd_dup2(fd, fd2))
6970 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006972 if (res < 0)
6973 return posix_error();
6974 Py_INCREF(Py_None);
6975 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006976}
6977
Ross Lagerwall7807c352011-03-17 20:20:30 +02006978#ifdef HAVE_LOCKF
6979PyDoc_STRVAR(posix_lockf__doc__,
6980"lockf(fd, cmd, len)\n\n\
6981Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
6982fd is an open file descriptor.\n\
6983cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
6984F_TEST.\n\
6985len specifies the section of the file to lock.");
6986
6987static PyObject *
6988posix_lockf(PyObject *self, PyObject *args)
6989{
6990 int fd, cmd, res;
6991 off_t len;
6992 if (!PyArg_ParseTuple(args, "iiO&:lockf",
6993 &fd, &cmd, _parse_off_t, &len))
6994 return NULL;
6995
6996 Py_BEGIN_ALLOW_THREADS
6997 res = lockf(fd, cmd, len);
6998 Py_END_ALLOW_THREADS
6999
7000 if (res < 0)
7001 return posix_error();
7002
7003 Py_RETURN_NONE;
7004}
7005#endif
7006
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007007
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007008PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007009"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007010Set the current position of a file descriptor.\n\
7011Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007012
Barry Warsaw53699e91996-12-10 23:23:01 +00007013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007014posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007015{
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007017#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007019#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007021#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007022 PyObject *posobj;
7023 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007025#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7027 switch (how) {
7028 case 0: how = SEEK_SET; break;
7029 case 1: how = SEEK_CUR; break;
7030 case 2: how = SEEK_END; break;
7031 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007032#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007033
Ross Lagerwall8e749672011-03-17 21:54:07 +02007034#if !defined(HAVE_LARGEFILE_SUPPORT)
7035 pos = PyLong_AsLong(posobj);
7036#else
7037 pos = PyLong_AsLongLong(posobj);
7038#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 if (PyErr_Occurred())
7040 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007041
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 if (!_PyVerify_fd(fd))
7043 return posix_error();
7044 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007045#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007047#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007049#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007050 Py_END_ALLOW_THREADS
7051 if (res < 0)
7052 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007053
7054#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007056#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007058#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007059}
7060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007062PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007063"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007064Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007065
Barry Warsaw53699e91996-12-10 23:23:01 +00007066static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007067posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007068{
Victor Stinner8c62be82010-05-06 00:08:46 +00007069 int fd, size;
7070 Py_ssize_t n;
7071 PyObject *buffer;
7072 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7073 return NULL;
7074 if (size < 0) {
7075 errno = EINVAL;
7076 return posix_error();
7077 }
7078 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7079 if (buffer == NULL)
7080 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007081 if (!_PyVerify_fd(fd)) {
7082 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007083 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007084 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 Py_BEGIN_ALLOW_THREADS
7086 n = read(fd, PyBytes_AS_STRING(buffer), size);
7087 Py_END_ALLOW_THREADS
7088 if (n < 0) {
7089 Py_DECREF(buffer);
7090 return posix_error();
7091 }
7092 if (n != size)
7093 _PyBytes_Resize(&buffer, n);
7094 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007095}
7096
Ross Lagerwall7807c352011-03-17 20:20:30 +02007097#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7098 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007099static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007100iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7101{
7102 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007103 Py_ssize_t blen, total = 0;
7104
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007105 *iov = PyMem_New(struct iovec, cnt);
7106 if (*iov == NULL) {
7107 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007108 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007109 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007110
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007111 *buf = PyMem_New(Py_buffer, cnt);
7112 if (*buf == NULL) {
7113 PyMem_Del(*iov);
7114 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007115 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007116 }
7117
7118 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007119 PyObject *item = PySequence_GetItem(seq, i);
7120 if (item == NULL)
7121 goto fail;
7122 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7123 Py_DECREF(item);
7124 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007125 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007126 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007127 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007128 blen = (*buf)[i].len;
7129 (*iov)[i].iov_len = blen;
7130 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007131 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007132 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007133
7134fail:
7135 PyMem_Del(*iov);
7136 for (j = 0; j < i; j++) {
7137 PyBuffer_Release(&(*buf)[j]);
7138 }
7139 PyMem_Del(*buf);
7140 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007141}
7142
7143static void
7144iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7145{
7146 int i;
7147 PyMem_Del(iov);
7148 for (i = 0; i < cnt; i++) {
7149 PyBuffer_Release(&buf[i]);
7150 }
7151 PyMem_Del(buf);
7152}
7153#endif
7154
Ross Lagerwall7807c352011-03-17 20:20:30 +02007155#ifdef HAVE_READV
7156PyDoc_STRVAR(posix_readv__doc__,
7157"readv(fd, buffers) -> bytesread\n\n\
7158Read from a file descriptor into a number of writable buffers. buffers\n\
7159is an arbitrary sequence of writable buffers.\n\
7160Returns the total number of bytes read.");
7161
7162static PyObject *
7163posix_readv(PyObject *self, PyObject *args)
7164{
7165 int fd, cnt;
7166 Py_ssize_t n;
7167 PyObject *seq;
7168 struct iovec *iov;
7169 Py_buffer *buf;
7170
7171 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7172 return NULL;
7173 if (!PySequence_Check(seq)) {
7174 PyErr_SetString(PyExc_TypeError,
7175 "readv() arg 2 must be a sequence");
7176 return NULL;
7177 }
7178 cnt = PySequence_Size(seq);
7179
7180 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7181 return NULL;
7182
7183 Py_BEGIN_ALLOW_THREADS
7184 n = readv(fd, iov, cnt);
7185 Py_END_ALLOW_THREADS
7186
7187 iov_cleanup(iov, buf, cnt);
7188 return PyLong_FromSsize_t(n);
7189}
7190#endif
7191
7192#ifdef HAVE_PREAD
7193PyDoc_STRVAR(posix_pread__doc__,
7194"pread(fd, buffersize, offset) -> string\n\n\
7195Read from a file descriptor, fd, at a position of offset. It will read up\n\
7196to buffersize number of bytes. The file offset remains unchanged.");
7197
7198static PyObject *
7199posix_pread(PyObject *self, PyObject *args)
7200{
7201 int fd, size;
7202 off_t offset;
7203 Py_ssize_t n;
7204 PyObject *buffer;
7205 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7206 return NULL;
7207
7208 if (size < 0) {
7209 errno = EINVAL;
7210 return posix_error();
7211 }
7212 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7213 if (buffer == NULL)
7214 return NULL;
7215 if (!_PyVerify_fd(fd)) {
7216 Py_DECREF(buffer);
7217 return posix_error();
7218 }
7219 Py_BEGIN_ALLOW_THREADS
7220 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7221 Py_END_ALLOW_THREADS
7222 if (n < 0) {
7223 Py_DECREF(buffer);
7224 return posix_error();
7225 }
7226 if (n != size)
7227 _PyBytes_Resize(&buffer, n);
7228 return buffer;
7229}
7230#endif
7231
7232PyDoc_STRVAR(posix_write__doc__,
7233"write(fd, string) -> byteswritten\n\n\
7234Write a string to a file descriptor.");
7235
7236static PyObject *
7237posix_write(PyObject *self, PyObject *args)
7238{
7239 Py_buffer pbuf;
7240 int fd;
7241 Py_ssize_t size, len;
7242
7243 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7244 return NULL;
7245 if (!_PyVerify_fd(fd)) {
7246 PyBuffer_Release(&pbuf);
7247 return posix_error();
7248 }
7249 len = pbuf.len;
7250 Py_BEGIN_ALLOW_THREADS
7251#if defined(MS_WIN64) || defined(MS_WINDOWS)
7252 if (len > INT_MAX)
7253 len = INT_MAX;
7254 size = write(fd, pbuf.buf, (int)len);
7255#else
7256 size = write(fd, pbuf.buf, len);
7257#endif
7258 Py_END_ALLOW_THREADS
7259 PyBuffer_Release(&pbuf);
7260 if (size < 0)
7261 return posix_error();
7262 return PyLong_FromSsize_t(size);
7263}
7264
7265#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007266PyDoc_STRVAR(posix_sendfile__doc__,
7267"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7268sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7269 -> byteswritten\n\
7270Copy nbytes bytes from file descriptor in to file descriptor out.");
7271
7272static PyObject *
7273posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7274{
7275 int in, out;
7276 Py_ssize_t ret;
7277 off_t offset;
7278
7279#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7280#ifndef __APPLE__
7281 Py_ssize_t len;
7282#endif
7283 PyObject *headers = NULL, *trailers = NULL;
7284 Py_buffer *hbuf, *tbuf;
7285 off_t sbytes;
7286 struct sf_hdtr sf;
7287 int flags = 0;
7288 sf.headers = NULL;
7289 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007290 static char *keywords[] = {"out", "in",
7291 "offset", "count",
7292 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007293
7294#ifdef __APPLE__
7295 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007296 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007297#else
7298 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007299 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007300#endif
7301 &headers, &trailers, &flags))
7302 return NULL;
7303 if (headers != NULL) {
7304 if (!PySequence_Check(headers)) {
7305 PyErr_SetString(PyExc_TypeError,
7306 "sendfile() headers must be a sequence or None");
7307 return NULL;
7308 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007309 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007310 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007311 if (sf.hdr_cnt > 0 &&
7312 !(i = iov_setup(&(sf.headers), &hbuf,
7313 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007314 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007315#ifdef __APPLE__
7316 sbytes += i;
7317#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007318 }
7319 }
7320 if (trailers != NULL) {
7321 if (!PySequence_Check(trailers)) {
7322 PyErr_SetString(PyExc_TypeError,
7323 "sendfile() trailers must be a sequence or None");
7324 return NULL;
7325 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007326 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007327 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007328 if (sf.trl_cnt > 0 &&
7329 !(i = iov_setup(&(sf.trailers), &tbuf,
7330 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007331 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007332#ifdef __APPLE__
7333 sbytes += i;
7334#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007335 }
7336 }
7337
7338 Py_BEGIN_ALLOW_THREADS
7339#ifdef __APPLE__
7340 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7341#else
7342 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7343#endif
7344 Py_END_ALLOW_THREADS
7345
7346 if (sf.headers != NULL)
7347 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7348 if (sf.trailers != NULL)
7349 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7350
7351 if (ret < 0) {
7352 if ((errno == EAGAIN) || (errno == EBUSY)) {
7353 if (sbytes != 0) {
7354 // some data has been sent
7355 goto done;
7356 }
7357 else {
7358 // no data has been sent; upper application is supposed
7359 // to retry on EAGAIN or EBUSY
7360 return posix_error();
7361 }
7362 }
7363 return posix_error();
7364 }
7365 goto done;
7366
7367done:
7368 #if !defined(HAVE_LARGEFILE_SUPPORT)
7369 return Py_BuildValue("l", sbytes);
7370 #else
7371 return Py_BuildValue("L", sbytes);
7372 #endif
7373
7374#else
7375 Py_ssize_t count;
7376 PyObject *offobj;
7377 static char *keywords[] = {"out", "in",
7378 "offset", "count", NULL};
7379 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7380 keywords, &out, &in, &offobj, &count))
7381 return NULL;
7382#ifdef linux
7383 if (offobj == Py_None) {
7384 Py_BEGIN_ALLOW_THREADS
7385 ret = sendfile(out, in, NULL, count);
7386 Py_END_ALLOW_THREADS
7387 if (ret < 0)
7388 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007389 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007390 }
7391#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007392 if (!_parse_off_t(offobj, &offset))
7393 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007394 Py_BEGIN_ALLOW_THREADS
7395 ret = sendfile(out, in, &offset, count);
7396 Py_END_ALLOW_THREADS
7397 if (ret < 0)
7398 return posix_error();
7399 return Py_BuildValue("n", ret);
7400#endif
7401}
7402#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007403
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007404PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007405"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007406Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007407
Barry Warsaw53699e91996-12-10 23:23:01 +00007408static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007409posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007410{
Victor Stinner8c62be82010-05-06 00:08:46 +00007411 int fd;
7412 STRUCT_STAT st;
7413 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007414 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007415 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007416#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007417 /* on OpenVMS we must ensure that all bytes are written to the file */
7418 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007419#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007420 if (!_PyVerify_fd(fd))
7421 return posix_error();
7422 Py_BEGIN_ALLOW_THREADS
7423 res = FSTAT(fd, &st);
7424 Py_END_ALLOW_THREADS
7425 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007426#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007427 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00007428#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007430#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007431 }
Tim Peters5aa91602002-01-30 05:46:57 +00007432
Victor Stinner4195b5c2012-02-08 23:03:19 +01007433 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007434}
7435
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007436PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007437"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007438Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007439connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007440
7441static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007442posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007443{
Victor Stinner8c62be82010-05-06 00:08:46 +00007444 int fd;
7445 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7446 return NULL;
7447 if (!_PyVerify_fd(fd))
7448 return PyBool_FromLong(0);
7449 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007450}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007451
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007452#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007453PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007454"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007455Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007456
Barry Warsaw53699e91996-12-10 23:23:01 +00007457static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007458posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007459{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007460#if defined(PYOS_OS2)
7461 HFILE read, write;
7462 APIRET rc;
7463
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007464 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007465 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007466 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007467
7468 return Py_BuildValue("(ii)", read, write);
7469#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007470#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007471 int fds[2];
7472 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007473 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007474 if (res != 0)
7475 return posix_error();
7476 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007477#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007478 HANDLE read, write;
7479 int read_fd, write_fd;
7480 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007481 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007482 if (!ok)
7483 return win32_error("CreatePipe", NULL);
7484 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7485 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7486 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007487#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007488#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007489}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007490#endif /* HAVE_PIPE */
7491
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007492#ifdef HAVE_PIPE2
7493PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007494"pipe2(flags) -> (read_end, write_end)\n\n\
7495Create a pipe with flags set atomically.\n\
7496flags can be constructed by ORing together one or more of these values:\n\
7497O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007498");
7499
7500static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007501posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007502{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007503 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007504 int fds[2];
7505 int res;
7506
Charles-François Natali368f34b2011-06-06 19:49:47 +02007507 flags = PyLong_AsLong(arg);
7508 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007509 return NULL;
7510
7511 res = pipe2(fds, flags);
7512 if (res != 0)
7513 return posix_error();
7514 return Py_BuildValue("(ii)", fds[0], fds[1]);
7515}
7516#endif /* HAVE_PIPE2 */
7517
Ross Lagerwall7807c352011-03-17 20:20:30 +02007518#ifdef HAVE_WRITEV
7519PyDoc_STRVAR(posix_writev__doc__,
7520"writev(fd, buffers) -> byteswritten\n\n\
7521Write the contents of buffers to a file descriptor, where buffers is an\n\
7522arbitrary sequence of buffers.\n\
7523Returns the total bytes written.");
7524
7525static PyObject *
7526posix_writev(PyObject *self, PyObject *args)
7527{
7528 int fd, cnt;
7529 Py_ssize_t res;
7530 PyObject *seq;
7531 struct iovec *iov;
7532 Py_buffer *buf;
7533 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7534 return NULL;
7535 if (!PySequence_Check(seq)) {
7536 PyErr_SetString(PyExc_TypeError,
7537 "writev() arg 2 must be a sequence");
7538 return NULL;
7539 }
7540 cnt = PySequence_Size(seq);
7541
7542 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7543 return NULL;
7544 }
7545
7546 Py_BEGIN_ALLOW_THREADS
7547 res = writev(fd, iov, cnt);
7548 Py_END_ALLOW_THREADS
7549
7550 iov_cleanup(iov, buf, cnt);
7551 return PyLong_FromSsize_t(res);
7552}
7553#endif
7554
7555#ifdef HAVE_PWRITE
7556PyDoc_STRVAR(posix_pwrite__doc__,
7557"pwrite(fd, string, offset) -> byteswritten\n\n\
7558Write string to a file descriptor, fd, from offset, leaving the file\n\
7559offset unchanged.");
7560
7561static PyObject *
7562posix_pwrite(PyObject *self, PyObject *args)
7563{
7564 Py_buffer pbuf;
7565 int fd;
7566 off_t offset;
7567 Py_ssize_t size;
7568
7569 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7570 return NULL;
7571
7572 if (!_PyVerify_fd(fd)) {
7573 PyBuffer_Release(&pbuf);
7574 return posix_error();
7575 }
7576 Py_BEGIN_ALLOW_THREADS
7577 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7578 Py_END_ALLOW_THREADS
7579 PyBuffer_Release(&pbuf);
7580 if (size < 0)
7581 return posix_error();
7582 return PyLong_FromSsize_t(size);
7583}
7584#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007585
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007586#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007587PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007588"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007589Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007590
Barry Warsaw53699e91996-12-10 23:23:01 +00007591static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007592posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007593{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007594 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007595 char *filename;
7596 int mode = 0666;
7597 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007598 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
7599 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007601 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007602 Py_BEGIN_ALLOW_THREADS
7603 res = mkfifo(filename, mode);
7604 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007605 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007606 if (res < 0)
7607 return posix_error();
7608 Py_INCREF(Py_None);
7609 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007610}
7611#endif
7612
7613
Neal Norwitz11690112002-07-30 01:08:28 +00007614#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007615PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007616"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007617Create a filesystem node (file, device special file or named pipe)\n\
7618named filename. mode specifies both the permissions to use and the\n\
7619type of node to be created, being combined (bitwise OR) with one of\n\
7620S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007621device defines the newly created device special file (probably using\n\
7622os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007623
7624
7625static PyObject *
7626posix_mknod(PyObject *self, PyObject *args)
7627{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007628 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007629 char *filename;
7630 int mode = 0600;
7631 int device = 0;
7632 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007633 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
7634 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00007635 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007636 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007637 Py_BEGIN_ALLOW_THREADS
7638 res = mknod(filename, mode, device);
7639 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007640 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007641 if (res < 0)
7642 return posix_error();
7643 Py_INCREF(Py_None);
7644 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007645}
7646#endif
7647
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007648#ifdef HAVE_DEVICE_MACROS
7649PyDoc_STRVAR(posix_major__doc__,
7650"major(device) -> major number\n\
7651Extracts a device major number from a raw device number.");
7652
7653static PyObject *
7654posix_major(PyObject *self, PyObject *args)
7655{
Victor Stinner8c62be82010-05-06 00:08:46 +00007656 int device;
7657 if (!PyArg_ParseTuple(args, "i:major", &device))
7658 return NULL;
7659 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007660}
7661
7662PyDoc_STRVAR(posix_minor__doc__,
7663"minor(device) -> minor number\n\
7664Extracts a device minor number from a raw device number.");
7665
7666static PyObject *
7667posix_minor(PyObject *self, PyObject *args)
7668{
Victor Stinner8c62be82010-05-06 00:08:46 +00007669 int device;
7670 if (!PyArg_ParseTuple(args, "i:minor", &device))
7671 return NULL;
7672 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007673}
7674
7675PyDoc_STRVAR(posix_makedev__doc__,
7676"makedev(major, minor) -> device number\n\
7677Composes a raw device number from the major and minor device numbers.");
7678
7679static PyObject *
7680posix_makedev(PyObject *self, PyObject *args)
7681{
Victor Stinner8c62be82010-05-06 00:08:46 +00007682 int major, minor;
7683 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7684 return NULL;
7685 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007686}
7687#endif /* device macros */
7688
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007689
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007690#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007691PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007692"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007693Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007694
Barry Warsaw53699e91996-12-10 23:23:01 +00007695static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007696posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007697{
Victor Stinner8c62be82010-05-06 00:08:46 +00007698 int fd;
7699 off_t length;
7700 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007701
Ross Lagerwall7807c352011-03-17 20:20:30 +02007702 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007703 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007704
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 Py_BEGIN_ALLOW_THREADS
7706 res = ftruncate(fd, length);
7707 Py_END_ALLOW_THREADS
7708 if (res < 0)
7709 return posix_error();
7710 Py_INCREF(Py_None);
7711 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007712}
7713#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007714
Ross Lagerwall7807c352011-03-17 20:20:30 +02007715#ifdef HAVE_TRUNCATE
7716PyDoc_STRVAR(posix_truncate__doc__,
7717"truncate(path, length)\n\n\
7718Truncate the file given by path to length bytes.");
7719
7720static PyObject *
7721posix_truncate(PyObject *self, PyObject *args)
7722{
7723 PyObject *opath;
7724 const char *path;
7725 off_t length;
7726 int res;
7727
7728 if (!PyArg_ParseTuple(args, "O&O&:truncate",
7729 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
7730 return NULL;
7731 path = PyBytes_AsString(opath);
7732
7733 Py_BEGIN_ALLOW_THREADS
7734 res = truncate(path, length);
7735 Py_END_ALLOW_THREADS
7736 Py_DECREF(opath);
7737 if (res < 0)
7738 return posix_error();
7739 Py_RETURN_NONE;
7740}
7741#endif
7742
7743#ifdef HAVE_POSIX_FALLOCATE
7744PyDoc_STRVAR(posix_posix_fallocate__doc__,
7745"posix_fallocate(fd, offset, len)\n\n\
7746Ensures that enough disk space is allocated for the file specified by fd\n\
7747starting from offset and continuing for len bytes.");
7748
7749static PyObject *
7750posix_posix_fallocate(PyObject *self, PyObject *args)
7751{
7752 off_t len, offset;
7753 int res, fd;
7754
7755 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7756 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7757 return NULL;
7758
7759 Py_BEGIN_ALLOW_THREADS
7760 res = posix_fallocate(fd, offset, len);
7761 Py_END_ALLOW_THREADS
7762 if (res != 0) {
7763 errno = res;
7764 return posix_error();
7765 }
7766 Py_RETURN_NONE;
7767}
7768#endif
7769
7770#ifdef HAVE_POSIX_FADVISE
7771PyDoc_STRVAR(posix_posix_fadvise__doc__,
7772"posix_fadvise(fd, offset, len, advice)\n\n\
7773Announces an intention to access data in a specific pattern thus allowing\n\
7774the kernel to make optimizations.\n\
7775The advice applies to the region of the file specified by fd starting at\n\
7776offset and continuing for len bytes.\n\
7777advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7778POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7779POSIX_FADV_DONTNEED.");
7780
7781static PyObject *
7782posix_posix_fadvise(PyObject *self, PyObject *args)
7783{
7784 off_t len, offset;
7785 int res, fd, advice;
7786
7787 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
7788 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
7789 return NULL;
7790
7791 Py_BEGIN_ALLOW_THREADS
7792 res = posix_fadvise(fd, offset, len, advice);
7793 Py_END_ALLOW_THREADS
7794 if (res != 0) {
7795 errno = res;
7796 return posix_error();
7797 }
7798 Py_RETURN_NONE;
7799}
7800#endif
7801
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007802#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007803PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007804"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007805Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007806
Fred Drake762e2061999-08-26 17:23:54 +00007807/* Save putenv() parameters as values here, so we can collect them when they
7808 * get re-set with another call for the same key. */
7809static PyObject *posix_putenv_garbage;
7810
Tim Peters5aa91602002-01-30 05:46:57 +00007811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007812posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007813{
Victor Stinner84ae1182010-05-06 22:05:07 +00007814 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007815#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01007816 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007817 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01007818
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01007820 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01007821 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007823
Victor Stinner65170952011-11-22 22:16:17 +01007824 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00007825 if (newstr == NULL) {
7826 PyErr_NoMemory();
7827 goto error;
7828 }
Victor Stinner65170952011-11-22 22:16:17 +01007829 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
7830 PyErr_Format(PyExc_ValueError,
7831 "the environment variable is longer than %u characters",
7832 _MAX_ENV);
7833 goto error;
7834 }
7835
Victor Stinner8c62be82010-05-06 00:08:46 +00007836 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02007837 if (newenv == NULL)
7838 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007841 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007842 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007843#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007844 PyObject *os1, *os2;
7845 char *s1, *s2;
7846 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007847
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007848 if (!PyArg_ParseTuple(args,
7849 "O&O&:putenv",
7850 PyUnicode_FSConverter, &os1,
7851 PyUnicode_FSConverter, &os2))
7852 return NULL;
7853 s1 = PyBytes_AsString(os1);
7854 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00007855
Victor Stinner65170952011-11-22 22:16:17 +01007856 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01007857 if (newstr == NULL) {
7858 PyErr_NoMemory();
7859 goto error;
7860 }
7861
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00007863 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007865 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007866 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007867#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007868
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 /* Install the first arg and newstr in posix_putenv_garbage;
7870 * this will cause previous value to be collected. This has to
7871 * happen after the real putenv() call because the old value
7872 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01007873 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 /* really not much we can do; just leak */
7875 PyErr_Clear();
7876 }
7877 else {
7878 Py_DECREF(newstr);
7879 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007880
Martin v. Löwis011e8422009-05-05 04:43:17 +00007881#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007882 Py_DECREF(os1);
7883 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007884#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007885 Py_RETURN_NONE;
7886
7887error:
7888#ifndef MS_WINDOWS
7889 Py_DECREF(os1);
7890 Py_DECREF(os2);
7891#endif
7892 Py_XDECREF(newstr);
7893 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00007894}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007895#endif /* putenv */
7896
Guido van Rossumc524d952001-10-19 01:31:59 +00007897#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007898PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007899"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007900Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007901
7902static PyObject *
7903posix_unsetenv(PyObject *self, PyObject *args)
7904{
Victor Stinner65170952011-11-22 22:16:17 +01007905 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01007906#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01007907 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01007908#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007909
7910 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00007911
Victor Stinner65170952011-11-22 22:16:17 +01007912 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00007913 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007914
Victor Stinner984890f2011-11-24 13:53:38 +01007915#ifdef HAVE_BROKEN_UNSETENV
7916 unsetenv(PyBytes_AS_STRING(name));
7917#else
Victor Stinner65170952011-11-22 22:16:17 +01007918 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06007919 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06007920 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01007921 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06007922 }
Victor Stinner984890f2011-11-24 13:53:38 +01007923#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007924
Victor Stinner8c62be82010-05-06 00:08:46 +00007925 /* Remove the key from posix_putenv_garbage;
7926 * this will cause it to be collected. This has to
7927 * happen after the real unsetenv() call because the
7928 * old value was still accessible until then.
7929 */
Victor Stinner65170952011-11-22 22:16:17 +01007930 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 /* really not much we can do; just leak */
7932 PyErr_Clear();
7933 }
Victor Stinner65170952011-11-22 22:16:17 +01007934 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00007935 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00007936}
7937#endif /* unsetenv */
7938
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007939PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007940"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007941Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007942
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007944posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007945{
Victor Stinner8c62be82010-05-06 00:08:46 +00007946 int code;
7947 char *message;
7948 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7949 return NULL;
7950 message = strerror(code);
7951 if (message == NULL) {
7952 PyErr_SetString(PyExc_ValueError,
7953 "strerror() argument out of range");
7954 return NULL;
7955 }
Victor Stinner1b579672011-12-17 05:47:23 +01007956 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007957}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007958
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007959
Guido van Rossumc9641791998-08-04 15:26:23 +00007960#ifdef HAVE_SYS_WAIT_H
7961
Fred Drake106c1a02002-04-23 15:58:02 +00007962#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007963PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007964"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007965Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007966
7967static PyObject *
7968posix_WCOREDUMP(PyObject *self, PyObject *args)
7969{
Victor Stinner8c62be82010-05-06 00:08:46 +00007970 WAIT_TYPE status;
7971 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007972
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7974 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007975
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007977}
7978#endif /* WCOREDUMP */
7979
7980#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007981PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007982"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007983Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007984job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007985
7986static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007987posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007988{
Victor Stinner8c62be82010-05-06 00:08:46 +00007989 WAIT_TYPE status;
7990 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007991
Victor Stinner8c62be82010-05-06 00:08:46 +00007992 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7993 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007994
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007996}
7997#endif /* WIFCONTINUED */
7998
Guido van Rossumc9641791998-08-04 15:26:23 +00007999#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008000PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008001"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008002Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008003
8004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008005posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008006{
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 WAIT_TYPE status;
8008 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008009
Victor Stinner8c62be82010-05-06 00:08:46 +00008010 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8011 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008012
Victor Stinner8c62be82010-05-06 00:08:46 +00008013 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008014}
8015#endif /* WIFSTOPPED */
8016
8017#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008018PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008019"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008020Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008021
8022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008023posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008024{
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 WAIT_TYPE status;
8026 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008027
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8029 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008030
Victor Stinner8c62be82010-05-06 00:08:46 +00008031 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008032}
8033#endif /* WIFSIGNALED */
8034
8035#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008036PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008037"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008038Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008039system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008040
8041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008042posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008043{
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 WAIT_TYPE status;
8045 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008046
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8048 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008049
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008051}
8052#endif /* WIFEXITED */
8053
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008054#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008055PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008056"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008057Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008058
8059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008060posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008061{
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 WAIT_TYPE status;
8063 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008064
Victor Stinner8c62be82010-05-06 00:08:46 +00008065 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8066 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008067
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008069}
8070#endif /* WEXITSTATUS */
8071
8072#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008073PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008074"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008075Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008076value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008077
8078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008079posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008080{
Victor Stinner8c62be82010-05-06 00:08:46 +00008081 WAIT_TYPE status;
8082 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008083
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8085 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008086
Victor Stinner8c62be82010-05-06 00:08:46 +00008087 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008088}
8089#endif /* WTERMSIG */
8090
8091#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008092PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008093"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008094Return the signal that stopped the process that provided\n\
8095the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008096
8097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008098posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008099{
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 WAIT_TYPE status;
8101 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008102
Victor Stinner8c62be82010-05-06 00:08:46 +00008103 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8104 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008105
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008107}
8108#endif /* WSTOPSIG */
8109
8110#endif /* HAVE_SYS_WAIT_H */
8111
8112
Thomas Wouters477c8d52006-05-27 19:21:47 +00008113#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008114#ifdef _SCO_DS
8115/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8116 needed definitions in sys/statvfs.h */
8117#define _SVID3
8118#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008119#include <sys/statvfs.h>
8120
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008121static PyObject*
8122_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008123 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8124 if (v == NULL)
8125 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008126
8127#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008128 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8129 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8130 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8131 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8132 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8133 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8134 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8135 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8136 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8137 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008138#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008139 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8140 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8141 PyStructSequence_SET_ITEM(v, 2,
8142 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8143 PyStructSequence_SET_ITEM(v, 3,
8144 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8145 PyStructSequence_SET_ITEM(v, 4,
8146 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8147 PyStructSequence_SET_ITEM(v, 5,
8148 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8149 PyStructSequence_SET_ITEM(v, 6,
8150 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8151 PyStructSequence_SET_ITEM(v, 7,
8152 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8153 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8154 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008155#endif
8156
Victor Stinner8c62be82010-05-06 00:08:46 +00008157 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008158}
8159
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008160PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008161"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008162Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008163
8164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008165posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008166{
Victor Stinner8c62be82010-05-06 00:08:46 +00008167 int fd, res;
8168 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008169
Victor Stinner8c62be82010-05-06 00:08:46 +00008170 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8171 return NULL;
8172 Py_BEGIN_ALLOW_THREADS
8173 res = fstatvfs(fd, &st);
8174 Py_END_ALLOW_THREADS
8175 if (res != 0)
8176 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008177
Victor Stinner8c62be82010-05-06 00:08:46 +00008178 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008179}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008180#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008181
8182
Thomas Wouters477c8d52006-05-27 19:21:47 +00008183#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008184#include <sys/statvfs.h>
8185
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008186PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008187"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008188Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008189
8190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008191posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008192{
Victor Stinner6fa67772011-09-20 04:04:33 +02008193 PyObject *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 int res;
8195 struct statvfs st;
Victor Stinner6fa67772011-09-20 04:04:33 +02008196 if (!PyArg_ParseTuple(args, "O&:statvfs", PyUnicode_FSConverter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00008197 return NULL;
8198 Py_BEGIN_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008199 res = statvfs(PyBytes_AS_STRING(path), &st);
Victor Stinner8c62be82010-05-06 00:08:46 +00008200 Py_END_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008201 if (res != 0) {
8202 posix_error_with_filename(PyBytes_AS_STRING(path));
8203 Py_DECREF(path);
8204 return NULL;
8205 }
8206 Py_DECREF(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008207
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008209}
8210#endif /* HAVE_STATVFS */
8211
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008212#ifdef MS_WINDOWS
8213PyDoc_STRVAR(win32__getdiskusage__doc__,
8214"_getdiskusage(path) -> (total, free)\n\n\
8215Return disk usage statistics about the given path as (total, free) tuple.");
8216
8217static PyObject *
8218win32__getdiskusage(PyObject *self, PyObject *args)
8219{
8220 BOOL retval;
8221 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008222 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008223
Victor Stinner6139c1b2011-11-09 22:14:14 +01008224 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008225 return NULL;
8226
8227 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008228 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008229 Py_END_ALLOW_THREADS
8230 if (retval == 0)
8231 return PyErr_SetFromWindowsErr(0);
8232
8233 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8234}
8235#endif
8236
8237
Fred Drakec9680921999-12-13 16:37:25 +00008238/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8239 * It maps strings representing configuration variable names to
8240 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008241 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008242 * rarely-used constants. There are three separate tables that use
8243 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008244 *
8245 * This code is always included, even if none of the interfaces that
8246 * need it are included. The #if hackery needed to avoid it would be
8247 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008248 */
8249struct constdef {
8250 char *name;
8251 long value;
8252};
8253
Fred Drake12c6e2d1999-12-14 21:25:03 +00008254static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008255conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008256 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008257{
Christian Heimes217cfd12007-12-02 14:31:20 +00008258 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008259 *valuep = PyLong_AS_LONG(arg);
8260 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008261 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008262 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008263 /* look up the value in the table using a binary search */
8264 size_t lo = 0;
8265 size_t mid;
8266 size_t hi = tablesize;
8267 int cmp;
8268 const char *confname;
8269 if (!PyUnicode_Check(arg)) {
8270 PyErr_SetString(PyExc_TypeError,
8271 "configuration names must be strings or integers");
8272 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008273 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008274 confname = _PyUnicode_AsString(arg);
8275 if (confname == NULL)
8276 return 0;
8277 while (lo < hi) {
8278 mid = (lo + hi) / 2;
8279 cmp = strcmp(confname, table[mid].name);
8280 if (cmp < 0)
8281 hi = mid;
8282 else if (cmp > 0)
8283 lo = mid + 1;
8284 else {
8285 *valuep = table[mid].value;
8286 return 1;
8287 }
8288 }
8289 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8290 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008291 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008292}
8293
8294
8295#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8296static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008297#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008298 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008299#endif
8300#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008301 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008302#endif
Fred Drakec9680921999-12-13 16:37:25 +00008303#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008304 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008305#endif
8306#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008307 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008308#endif
8309#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008310 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008311#endif
8312#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008313 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008314#endif
8315#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008316 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008317#endif
8318#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008319 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008320#endif
8321#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008322 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008323#endif
8324#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008325 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008326#endif
8327#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008328 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008329#endif
8330#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008331 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008332#endif
8333#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008334 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008335#endif
8336#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008337 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008338#endif
8339#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008340 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008341#endif
8342#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008343 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008344#endif
8345#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008346 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008347#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008348#ifdef _PC_ACL_ENABLED
8349 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8350#endif
8351#ifdef _PC_MIN_HOLE_SIZE
8352 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8353#endif
8354#ifdef _PC_ALLOC_SIZE_MIN
8355 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8356#endif
8357#ifdef _PC_REC_INCR_XFER_SIZE
8358 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8359#endif
8360#ifdef _PC_REC_MAX_XFER_SIZE
8361 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8362#endif
8363#ifdef _PC_REC_MIN_XFER_SIZE
8364 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8365#endif
8366#ifdef _PC_REC_XFER_ALIGN
8367 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8368#endif
8369#ifdef _PC_SYMLINK_MAX
8370 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8371#endif
8372#ifdef _PC_XATTR_ENABLED
8373 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8374#endif
8375#ifdef _PC_XATTR_EXISTS
8376 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8377#endif
8378#ifdef _PC_TIMESTAMP_RESOLUTION
8379 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8380#endif
Fred Drakec9680921999-12-13 16:37:25 +00008381};
8382
Fred Drakec9680921999-12-13 16:37:25 +00008383static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008384conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008385{
8386 return conv_confname(arg, valuep, posix_constants_pathconf,
8387 sizeof(posix_constants_pathconf)
8388 / sizeof(struct constdef));
8389}
8390#endif
8391
8392#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008393PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008394"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008395Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008396If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008397
8398static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008399posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008400{
8401 PyObject *result = NULL;
8402 int name, fd;
8403
Fred Drake12c6e2d1999-12-14 21:25:03 +00008404 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8405 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008406 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008407
Stefan Krah0e803b32010-11-26 16:16:47 +00008408 errno = 0;
8409 limit = fpathconf(fd, name);
8410 if (limit == -1 && errno != 0)
8411 posix_error();
8412 else
8413 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008414 }
8415 return result;
8416}
8417#endif
8418
8419
8420#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008421PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008422"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008423Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008424If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008425
8426static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008427posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008428{
8429 PyObject *result = NULL;
8430 int name;
8431 char *path;
8432
8433 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
8434 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008435 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008436
Victor Stinner8c62be82010-05-06 00:08:46 +00008437 errno = 0;
8438 limit = pathconf(path, name);
8439 if (limit == -1 && errno != 0) {
8440 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008441 /* could be a path or name problem */
8442 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008443 else
Stefan Krah99439262010-11-26 12:58:05 +00008444 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008445 }
8446 else
8447 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008448 }
8449 return result;
8450}
8451#endif
8452
8453#ifdef HAVE_CONFSTR
8454static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008455#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008456 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008457#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008458#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008459 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008460#endif
8461#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008462 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008463#endif
Fred Draked86ed291999-12-15 15:34:33 +00008464#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008465 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008466#endif
8467#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008468 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008469#endif
8470#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008471 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008472#endif
8473#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008474 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008475#endif
Fred Drakec9680921999-12-13 16:37:25 +00008476#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008477 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008478#endif
8479#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008480 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008481#endif
8482#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008483 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008484#endif
8485#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008486 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008487#endif
8488#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008489 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008490#endif
8491#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008492 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008493#endif
8494#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008495 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008496#endif
8497#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008498 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008499#endif
Fred Draked86ed291999-12-15 15:34:33 +00008500#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008501 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008502#endif
Fred Drakec9680921999-12-13 16:37:25 +00008503#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008504 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008505#endif
Fred Draked86ed291999-12-15 15:34:33 +00008506#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008507 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008508#endif
8509#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008510 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008511#endif
8512#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008513 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008514#endif
8515#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008516 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008517#endif
Fred Drakec9680921999-12-13 16:37:25 +00008518#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008519 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008520#endif
8521#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008522 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008523#endif
8524#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008525 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008526#endif
8527#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008528 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008529#endif
8530#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008531 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008532#endif
8533#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008534 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008535#endif
8536#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008537 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008538#endif
8539#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008540 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008541#endif
8542#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008543 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008544#endif
8545#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008546 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008547#endif
8548#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008549 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008550#endif
8551#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008552 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008553#endif
8554#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008555 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008556#endif
8557#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008558 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008559#endif
8560#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008561 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008562#endif
8563#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008564 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008565#endif
Fred Draked86ed291999-12-15 15:34:33 +00008566#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008567 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008568#endif
8569#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008570 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008571#endif
8572#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008573 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008574#endif
8575#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008576 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008577#endif
8578#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008580#endif
8581#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008582 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008583#endif
8584#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008585 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008586#endif
8587#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008588 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008589#endif
8590#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008591 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008592#endif
8593#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008594 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008595#endif
8596#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008597 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008598#endif
8599#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008600 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008601#endif
8602#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008603 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008604#endif
Fred Drakec9680921999-12-13 16:37:25 +00008605};
8606
8607static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008608conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008609{
8610 return conv_confname(arg, valuep, posix_constants_confstr,
8611 sizeof(posix_constants_confstr)
8612 / sizeof(struct constdef));
8613}
8614
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008615PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008616"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008617Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008618
8619static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008620posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008621{
8622 PyObject *result = NULL;
8623 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008624 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008625 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008626
Victor Stinnercb043522010-09-10 23:49:04 +00008627 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8628 return NULL;
8629
8630 errno = 0;
8631 len = confstr(name, buffer, sizeof(buffer));
8632 if (len == 0) {
8633 if (errno) {
8634 posix_error();
8635 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008636 }
8637 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008638 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008639 }
8640 }
Victor Stinnercb043522010-09-10 23:49:04 +00008641
8642 if ((unsigned int)len >= sizeof(buffer)) {
8643 char *buf = PyMem_Malloc(len);
8644 if (buf == NULL)
8645 return PyErr_NoMemory();
8646 confstr(name, buf, len);
8647 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8648 PyMem_Free(buf);
8649 }
8650 else
8651 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008652 return result;
8653}
8654#endif
8655
8656
8657#ifdef HAVE_SYSCONF
8658static struct constdef posix_constants_sysconf[] = {
8659#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008660 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008661#endif
8662#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008663 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008664#endif
8665#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008666 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008667#endif
8668#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008669 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008670#endif
8671#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008672 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008673#endif
8674#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008675 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008676#endif
8677#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008678 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008679#endif
8680#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008681 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008682#endif
8683#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008684 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008685#endif
8686#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008687 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008688#endif
Fred Draked86ed291999-12-15 15:34:33 +00008689#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008690 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008691#endif
8692#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008693 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008694#endif
Fred Drakec9680921999-12-13 16:37:25 +00008695#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008696 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008697#endif
Fred Drakec9680921999-12-13 16:37:25 +00008698#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008699 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008700#endif
8701#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008702 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008703#endif
8704#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008705 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008706#endif
8707#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008708 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008709#endif
8710#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008711 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008712#endif
Fred Draked86ed291999-12-15 15:34:33 +00008713#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008714 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008715#endif
Fred Drakec9680921999-12-13 16:37:25 +00008716#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008717 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008718#endif
8719#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008720 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008721#endif
8722#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008723 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008724#endif
8725#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008726 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008727#endif
8728#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008729 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008730#endif
Fred Draked86ed291999-12-15 15:34:33 +00008731#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008732 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008733#endif
Fred Drakec9680921999-12-13 16:37:25 +00008734#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008735 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008736#endif
8737#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008738 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008739#endif
8740#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008741 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008742#endif
8743#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008744 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008745#endif
8746#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008747 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008748#endif
8749#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008750 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008751#endif
8752#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008753 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008754#endif
8755#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008756 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008757#endif
8758#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008759 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008760#endif
8761#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008762 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008763#endif
8764#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008765 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008766#endif
8767#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008768 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008769#endif
8770#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008771 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008772#endif
8773#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008774 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008775#endif
8776#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008777 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008778#endif
8779#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008780 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008781#endif
8782#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008783 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008784#endif
8785#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008786 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008787#endif
8788#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008789 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008790#endif
8791#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008792 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008793#endif
8794#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008795 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008796#endif
8797#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008798 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008799#endif
8800#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008801 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008802#endif
Fred Draked86ed291999-12-15 15:34:33 +00008803#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00008804 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008805#endif
Fred Drakec9680921999-12-13 16:37:25 +00008806#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008807 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008808#endif
8809#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008810 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008811#endif
8812#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008813 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008814#endif
Fred Draked86ed291999-12-15 15:34:33 +00008815#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008816 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008817#endif
Fred Drakec9680921999-12-13 16:37:25 +00008818#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00008819 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008820#endif
Fred Draked86ed291999-12-15 15:34:33 +00008821#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008822 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008823#endif
8824#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00008825 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008826#endif
Fred Drakec9680921999-12-13 16:37:25 +00008827#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008828 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008829#endif
8830#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008831 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008832#endif
8833#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008834 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008835#endif
8836#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008838#endif
Fred Draked86ed291999-12-15 15:34:33 +00008839#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008841#endif
Fred Drakec9680921999-12-13 16:37:25 +00008842#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008844#endif
8845#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00008846 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008847#endif
8848#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008849 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008850#endif
8851#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008853#endif
8854#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008856#endif
8857#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008859#endif
8860#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008862#endif
Fred Draked86ed291999-12-15 15:34:33 +00008863#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008865#endif
Fred Drakec9680921999-12-13 16:37:25 +00008866#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008867 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008868#endif
8869#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008870 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008871#endif
Fred Draked86ed291999-12-15 15:34:33 +00008872#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008874#endif
Fred Drakec9680921999-12-13 16:37:25 +00008875#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008876 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008877#endif
8878#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008879 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008880#endif
8881#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008882 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008883#endif
8884#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008885 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008886#endif
8887#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008888 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008889#endif
8890#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008891 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008892#endif
8893#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008894 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008895#endif
8896#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008897 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008898#endif
8899#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008900 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008901#endif
Fred Draked86ed291999-12-15 15:34:33 +00008902#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008903 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008904#endif
8905#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008906 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008907#endif
Fred Drakec9680921999-12-13 16:37:25 +00008908#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00008909 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008910#endif
8911#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008912 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008913#endif
8914#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008916#endif
8917#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008919#endif
8920#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008921 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008922#endif
8923#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008924 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008925#endif
8926#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00008927 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008928#endif
8929#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00008930 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008931#endif
8932#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008933 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008934#endif
8935#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008937#endif
8938#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008940#endif
8941#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008943#endif
8944#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008946#endif
8947#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008949#endif
8950#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008952#endif
8953#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00008954 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008955#endif
8956#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00008957 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008958#endif
8959#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008960 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008961#endif
8962#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008963 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008964#endif
8965#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00008966 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008967#endif
8968#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008969 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008970#endif
8971#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008972 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008973#endif
8974#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00008975 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008976#endif
8977#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008978 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008979#endif
8980#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008981 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008982#endif
8983#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008984 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008985#endif
8986#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00008987 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008988#endif
8989#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008990 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008991#endif
8992#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008993 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008994#endif
8995#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008996 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008997#endif
8998#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008999 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009000#endif
9001#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009002 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009003#endif
9004#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009005 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009006#endif
9007#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009008 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009009#endif
9010#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009011 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009012#endif
Fred Draked86ed291999-12-15 15:34:33 +00009013#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009014 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009015#endif
Fred Drakec9680921999-12-13 16:37:25 +00009016#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009017 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009018#endif
9019#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009020 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009021#endif
9022#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009023 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009024#endif
9025#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009026 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009027#endif
9028#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009029 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009030#endif
9031#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009032 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009033#endif
9034#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009035 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009036#endif
9037#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009038 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009039#endif
9040#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009041 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009042#endif
9043#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009044 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009045#endif
9046#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009047 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009048#endif
9049#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009050 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009051#endif
9052#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009054#endif
9055#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009056 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009057#endif
9058#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009059 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009060#endif
9061#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009063#endif
9064#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009065 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009066#endif
9067#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009069#endif
9070#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009072#endif
9073#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009074 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009075#endif
9076#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009078#endif
9079#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009081#endif
9082#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009084#endif
9085#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009087#endif
9088#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009090#endif
9091#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009092 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009093#endif
9094#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009096#endif
9097#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009098 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009099#endif
9100#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009102#endif
9103#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009105#endif
9106#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009108#endif
9109#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009111#endif
9112#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009114#endif
9115#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009117#endif
9118#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009119 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009120#endif
9121#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009123#endif
9124#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009125 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009126#endif
9127#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009128 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009129#endif
9130#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009131 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009132#endif
9133#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009134 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009135#endif
9136#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009137 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009138#endif
9139#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009140 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009141#endif
9142#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009144#endif
9145#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009147#endif
9148#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009149 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009150#endif
9151};
9152
9153static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009154conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009155{
9156 return conv_confname(arg, valuep, posix_constants_sysconf,
9157 sizeof(posix_constants_sysconf)
9158 / sizeof(struct constdef));
9159}
9160
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009161PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009162"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009163Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009164
9165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009166posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009167{
9168 PyObject *result = NULL;
9169 int name;
9170
9171 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9172 int value;
9173
9174 errno = 0;
9175 value = sysconf(name);
9176 if (value == -1 && errno != 0)
9177 posix_error();
9178 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009179 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009180 }
9181 return result;
9182}
9183#endif
9184
9185
Fred Drakebec628d1999-12-15 18:31:10 +00009186/* This code is used to ensure that the tables of configuration value names
9187 * are in sorted order as required by conv_confname(), and also to build the
9188 * the exported dictionaries that are used to publish information about the
9189 * names available on the host platform.
9190 *
9191 * Sorting the table at runtime ensures that the table is properly ordered
9192 * when used, even for platforms we're not able to test on. It also makes
9193 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009194 */
Fred Drakebec628d1999-12-15 18:31:10 +00009195
9196static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009197cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009198{
9199 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009200 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009201 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009203
9204 return strcmp(c1->name, c2->name);
9205}
9206
9207static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009208setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009210{
Fred Drakebec628d1999-12-15 18:31:10 +00009211 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009212 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009213
9214 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9215 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009216 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009217 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009218
Barry Warsaw3155db32000-04-13 15:20:40 +00009219 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009220 PyObject *o = PyLong_FromLong(table[i].value);
9221 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9222 Py_XDECREF(o);
9223 Py_DECREF(d);
9224 return -1;
9225 }
9226 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009227 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009228 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009229}
9230
Fred Drakebec628d1999-12-15 18:31:10 +00009231/* Return -1 on failure, 0 on success. */
9232static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009233setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009234{
9235#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009236 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009237 sizeof(posix_constants_pathconf)
9238 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009239 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009240 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009241#endif
9242#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009243 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009244 sizeof(posix_constants_confstr)
9245 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009246 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009247 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009248#endif
9249#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009250 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009251 sizeof(posix_constants_sysconf)
9252 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009253 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009254 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009255#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009256 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009257}
Fred Draked86ed291999-12-15 15:34:33 +00009258
9259
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009260PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009261"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009262Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009263in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009264
9265static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009266posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009267{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009268 abort();
9269 /*NOTREACHED*/
9270 Py_FatalError("abort() called from Python code didn't abort!");
9271 return NULL;
9272}
Fred Drakebec628d1999-12-15 18:31:10 +00009273
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009274#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009275PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009276"startfile(filepath [, operation]) - Start a file with its associated\n\
9277application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009278\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009279When \"operation\" is not specified or \"open\", this acts like\n\
9280double-clicking the file in Explorer, or giving the file name as an\n\
9281argument to the DOS \"start\" command: the file is opened with whatever\n\
9282application (if any) its extension is associated.\n\
9283When another \"operation\" is given, it specifies what should be done with\n\
9284the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009285\n\
9286startfile returns as soon as the associated application is launched.\n\
9287There is no option to wait for the application to close, and no way\n\
9288to retrieve the application's exit status.\n\
9289\n\
9290The filepath is relative to the current directory. If you want to use\n\
9291an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009292the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009293
9294static PyObject *
9295win32_startfile(PyObject *self, PyObject *args)
9296{
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 PyObject *ofilepath;
9298 char *filepath;
9299 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009300 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009301 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009302
Victor Stinnereb5657a2011-09-30 01:44:27 +02009303 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009304 if (!PyArg_ParseTuple(args, "U|s:startfile",
9305 &unipath, &operation)) {
9306 PyErr_Clear();
9307 goto normal;
9308 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009309
Victor Stinner8c62be82010-05-06 00:08:46 +00009310 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009311 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009313 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 PyErr_Clear();
9315 operation = NULL;
9316 goto normal;
9317 }
9318 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009319
Victor Stinnereb5657a2011-09-30 01:44:27 +02009320 wpath = PyUnicode_AsUnicode(unipath);
9321 if (wpath == NULL)
9322 goto normal;
9323 if (uoperation) {
9324 woperation = PyUnicode_AsUnicode(uoperation);
9325 if (woperation == NULL)
9326 goto normal;
9327 }
9328 else
9329 woperation = NULL;
9330
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009332 rc = ShellExecuteW((HWND)0, woperation, wpath,
9333 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009334 Py_END_ALLOW_THREADS
9335
Victor Stinnereb5657a2011-09-30 01:44:27 +02009336 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009337 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009338 win32_error_object("startfile", unipath);
9339 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009340 }
9341 Py_INCREF(Py_None);
9342 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009343
9344normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009345 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9346 PyUnicode_FSConverter, &ofilepath,
9347 &operation))
9348 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009349 if (win32_warn_bytes_api()) {
9350 Py_DECREF(ofilepath);
9351 return NULL;
9352 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 filepath = PyBytes_AsString(ofilepath);
9354 Py_BEGIN_ALLOW_THREADS
9355 rc = ShellExecute((HWND)0, operation, filepath,
9356 NULL, NULL, SW_SHOWNORMAL);
9357 Py_END_ALLOW_THREADS
9358 if (rc <= (HINSTANCE)32) {
9359 PyObject *errval = win32_error("startfile", filepath);
9360 Py_DECREF(ofilepath);
9361 return errval;
9362 }
9363 Py_DECREF(ofilepath);
9364 Py_INCREF(Py_None);
9365 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009366}
9367#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009368
Martin v. Löwis438b5342002-12-27 10:16:42 +00009369#ifdef HAVE_GETLOADAVG
9370PyDoc_STRVAR(posix_getloadavg__doc__,
9371"getloadavg() -> (float, float, float)\n\n\
9372Return the number of processes in the system run queue averaged over\n\
9373the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9374was unobtainable");
9375
9376static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009377posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009378{
9379 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009380 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009381 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9382 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009383 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009384 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009385}
9386#endif
9387
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009388PyDoc_STRVAR(device_encoding__doc__,
9389"device_encoding(fd) -> str\n\n\
9390Return a string describing the encoding of the device\n\
9391if the output is a terminal; else return None.");
9392
9393static PyObject *
9394device_encoding(PyObject *self, PyObject *args)
9395{
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009397
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9399 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009400
9401 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009402}
9403
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009404#ifdef __VMS
9405/* Use openssl random routine */
9406#include <openssl/rand.h>
9407PyDoc_STRVAR(vms_urandom__doc__,
9408"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009409Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009410
9411static PyObject*
9412vms_urandom(PyObject *self, PyObject *args)
9413{
Victor Stinner8c62be82010-05-06 00:08:46 +00009414 int howMany;
9415 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009416
Victor Stinner8c62be82010-05-06 00:08:46 +00009417 /* Read arguments */
9418 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9419 return NULL;
9420 if (howMany < 0)
9421 return PyErr_Format(PyExc_ValueError,
9422 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009423
Victor Stinner8c62be82010-05-06 00:08:46 +00009424 /* Allocate bytes */
9425 result = PyBytes_FromStringAndSize(NULL, howMany);
9426 if (result != NULL) {
9427 /* Get random data */
9428 if (RAND_pseudo_bytes((unsigned char*)
9429 PyBytes_AS_STRING(result),
9430 howMany) < 0) {
9431 Py_DECREF(result);
9432 return PyErr_Format(PyExc_ValueError,
9433 "RAND_pseudo_bytes");
9434 }
9435 }
9436 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009437}
9438#endif
9439
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009440#ifdef HAVE_SETRESUID
9441PyDoc_STRVAR(posix_setresuid__doc__,
9442"setresuid(ruid, euid, suid)\n\n\
9443Set the current process's real, effective, and saved user ids.");
9444
9445static PyObject*
9446posix_setresuid (PyObject *self, PyObject *args)
9447{
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 /* We assume uid_t is no larger than a long. */
9449 long ruid, euid, suid;
9450 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9451 return NULL;
9452 if (setresuid(ruid, euid, suid) < 0)
9453 return posix_error();
9454 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009455}
9456#endif
9457
9458#ifdef HAVE_SETRESGID
9459PyDoc_STRVAR(posix_setresgid__doc__,
9460"setresgid(rgid, egid, sgid)\n\n\
9461Set the current process's real, effective, and saved group ids.");
9462
9463static PyObject*
9464posix_setresgid (PyObject *self, PyObject *args)
9465{
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 /* We assume uid_t is no larger than a long. */
9467 long rgid, egid, sgid;
9468 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9469 return NULL;
9470 if (setresgid(rgid, egid, sgid) < 0)
9471 return posix_error();
9472 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009473}
9474#endif
9475
9476#ifdef HAVE_GETRESUID
9477PyDoc_STRVAR(posix_getresuid__doc__,
9478"getresuid() -> (ruid, euid, suid)\n\n\
9479Get tuple of the current process's real, effective, and saved user ids.");
9480
9481static PyObject*
9482posix_getresuid (PyObject *self, PyObject *noargs)
9483{
Victor Stinner8c62be82010-05-06 00:08:46 +00009484 uid_t ruid, euid, suid;
9485 long l_ruid, l_euid, l_suid;
9486 if (getresuid(&ruid, &euid, &suid) < 0)
9487 return posix_error();
9488 /* Force the values into long's as we don't know the size of uid_t. */
9489 l_ruid = ruid;
9490 l_euid = euid;
9491 l_suid = suid;
9492 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009493}
9494#endif
9495
9496#ifdef HAVE_GETRESGID
9497PyDoc_STRVAR(posix_getresgid__doc__,
9498"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009499Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009500
9501static PyObject*
9502posix_getresgid (PyObject *self, PyObject *noargs)
9503{
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 uid_t rgid, egid, sgid;
9505 long l_rgid, l_egid, l_sgid;
9506 if (getresgid(&rgid, &egid, &sgid) < 0)
9507 return posix_error();
9508 /* Force the values into long's as we don't know the size of uid_t. */
9509 l_rgid = rgid;
9510 l_egid = egid;
9511 l_sgid = sgid;
9512 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009513}
9514#endif
9515
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009516/* Posix *at family of functions:
9517 faccessat, fchmodat, fchownat, fstatat, futimesat,
9518 linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
9519 unlinkat, utimensat, mkfifoat */
9520
9521#ifdef HAVE_FACCESSAT
9522PyDoc_STRVAR(posix_faccessat__doc__,
9523"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
9524Like access() but if path is relative, it is taken as relative to dirfd.\n\
9525flags is optional and can be constructed by ORing together zero or more\n\
9526of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\n\
9527If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9528is interpreted relative to the current working directory.");
9529
9530static PyObject *
9531posix_faccessat(PyObject *self, PyObject *args)
9532{
9533 PyObject *opath;
9534 char *path;
9535 int mode;
9536 int res;
9537 int dirfd, flags = 0;
9538 if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
9539 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9540 return NULL;
9541 path = PyBytes_AsString(opath);
9542 Py_BEGIN_ALLOW_THREADS
9543 res = faccessat(dirfd, path, mode, flags);
9544 Py_END_ALLOW_THREADS
9545 Py_DECREF(opath);
9546 return PyBool_FromLong(res == 0);
9547}
9548#endif
9549
9550#ifdef HAVE_FCHMODAT
9551PyDoc_STRVAR(posix_fchmodat__doc__,
9552"fchmodat(dirfd, path, mode, flags=0)\n\n\
9553Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
9554flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9555If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9556is interpreted relative to the current working directory.");
9557
9558static PyObject *
9559posix_fchmodat(PyObject *self, PyObject *args)
9560{
9561 int dirfd, mode, res;
9562 int flags = 0;
9563 PyObject *opath;
9564 char *path;
9565
9566 if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
9567 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9568 return NULL;
9569
9570 path = PyBytes_AsString(opath);
9571
9572 Py_BEGIN_ALLOW_THREADS
9573 res = fchmodat(dirfd, path, mode, flags);
9574 Py_END_ALLOW_THREADS
9575 Py_DECREF(opath);
9576 if (res < 0)
9577 return posix_error();
9578 Py_RETURN_NONE;
9579}
9580#endif /* HAVE_FCHMODAT */
9581
9582#ifdef HAVE_FCHOWNAT
9583PyDoc_STRVAR(posix_fchownat__doc__,
9584"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
9585Like chown() but if path is relative, it is taken as relative to dirfd.\n\
9586flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9587If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9588is interpreted relative to the current working directory.");
9589
9590static PyObject *
9591posix_fchownat(PyObject *self, PyObject *args)
9592{
9593 PyObject *opath;
9594 int dirfd, res;
9595 long uid, gid;
9596 int flags = 0;
9597 char *path;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009598
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009599 if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
9600 &dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
9601 return NULL;
9602
9603 path = PyBytes_AsString(opath);
9604
9605 Py_BEGIN_ALLOW_THREADS
9606 res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
9607 Py_END_ALLOW_THREADS
9608 Py_DECREF(opath);
9609 if (res < 0)
9610 return posix_error();
9611 Py_RETURN_NONE;
9612}
9613#endif /* HAVE_FCHOWNAT */
9614
9615#ifdef HAVE_FSTATAT
9616PyDoc_STRVAR(posix_fstatat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01009617"fstatat(dirfd, path, flags=0) -> stat result\n\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009618Like stat() but if path is relative, it is taken as relative to dirfd.\n\
9619flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9620If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9621is interpreted relative to the current working directory.");
9622
9623static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01009624posix_fstatat(PyObject *self, PyObject *args)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009625{
9626 PyObject *opath;
9627 char *path;
9628 STRUCT_STAT st;
9629 int dirfd, res, flags = 0;
9630
Victor Stinner4195b5c2012-02-08 23:03:19 +01009631 if (!PyArg_ParseTuple(args, "iO&|i:fstatat",
9632 &dirfd, PyUnicode_FSConverter, &opath, &flags))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009633 return NULL;
9634 path = PyBytes_AsString(opath);
9635
9636 Py_BEGIN_ALLOW_THREADS
9637 res = fstatat(dirfd, path, &st, flags);
9638 Py_END_ALLOW_THREADS
9639 Py_DECREF(opath);
9640 if (res != 0)
9641 return posix_error();
9642
Victor Stinner4195b5c2012-02-08 23:03:19 +01009643 return _pystat_fromstructstat(&st);
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009644}
9645#endif
9646
9647#ifdef HAVE_FUTIMESAT
9648PyDoc_STRVAR(posix_futimesat__doc__,
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009649"futimesat(dirfd, path[, (atime, mtime)])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009650Like utime() but if path is relative, it is taken as relative to dirfd.\n\
9651If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9652is interpreted relative to the current working directory.");
9653
9654static PyObject *
9655posix_futimesat(PyObject *self, PyObject *args)
9656{
9657 PyObject *opath;
9658 char *path;
9659 int res, dirfd;
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009660 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009661 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009662 long ansec, mnsec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009663
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009664 if (!PyArg_ParseTuple(args, "iO&|O:futimesat",
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009665 &dirfd, PyUnicode_FSConverter, &opath, &arg))
9666 return NULL;
9667 path = PyBytes_AsString(opath);
9668 if (arg == Py_None) {
9669 /* optional time values not given */
9670 Py_BEGIN_ALLOW_THREADS
9671 res = futimesat(dirfd, path, NULL);
9672 Py_END_ALLOW_THREADS
9673 }
9674 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
9675 PyErr_SetString(PyExc_TypeError,
9676 "futimesat() arg 3 must be a tuple (atime, mtime)");
9677 Py_DECREF(opath);
9678 return NULL;
9679 }
9680 else {
Victor Stinner5d272cc2012-03-13 13:35:55 +01009681 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 0),
9682 &atime, &ansec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009683 Py_DECREF(opath);
9684 return NULL;
9685 }
Victor Stinner5d272cc2012-03-13 13:35:55 +01009686 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(arg, 1),
9687 &mtime, &mnsec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009688 Py_DECREF(opath);
9689 return NULL;
9690 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009691
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009692 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009693 {
9694#ifdef HAVE_UTIMENSAT
9695 struct timespec buf[2];
9696 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009697 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009698 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009699 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009700 res = utimensat(dirfd, path, buf, 0);
9701#else
9702 struct timeval buf[2];
9703 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009704 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009705 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009706 buf[1].tv_usec = mnsec / 1000;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009707 res = futimesat(dirfd, path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009708#endif
9709 }
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009710 Py_END_ALLOW_THREADS
9711 }
9712 Py_DECREF(opath);
9713 if (res < 0) {
9714 return posix_error();
9715 }
9716 Py_RETURN_NONE;
9717}
9718#endif
9719
9720#ifdef HAVE_LINKAT
9721PyDoc_STRVAR(posix_linkat__doc__,
9722"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
9723Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
9724and if dstpath is relative, it is taken as relative to dstfd.\n\
9725flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
9726If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
9727srcpath is interpreted relative to the current working directory. This\n\
9728also applies for dstpath.");
9729
9730static PyObject *
9731posix_linkat(PyObject *self, PyObject *args)
9732{
9733 PyObject *osrc, *odst;
9734 char *src, *dst;
9735 int res, srcfd, dstfd;
9736 int flags = 0;
9737
9738 if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
9739 &srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
9740 return NULL;
9741 src = PyBytes_AsString(osrc);
9742 dst = PyBytes_AsString(odst);
9743 Py_BEGIN_ALLOW_THREADS
9744 res = linkat(srcfd, src, dstfd, dst, flags);
9745 Py_END_ALLOW_THREADS
9746 Py_DECREF(osrc);
9747 Py_DECREF(odst);
9748 if (res < 0)
9749 return posix_error();
9750 Py_RETURN_NONE;
9751}
9752#endif /* HAVE_LINKAT */
9753
9754#ifdef HAVE_MKDIRAT
9755PyDoc_STRVAR(posix_mkdirat__doc__,
9756"mkdirat(dirfd, path, mode=0o777)\n\n\
9757Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
9758If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9759is interpreted relative to the current working directory.");
9760
9761static PyObject *
9762posix_mkdirat(PyObject *self, PyObject *args)
9763{
9764 int res, dirfd;
9765 PyObject *opath;
9766 char *path;
9767 int mode = 0777;
9768
9769 if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
9770 &dirfd, PyUnicode_FSConverter, &opath, &mode))
9771 return NULL;
9772 path = PyBytes_AsString(opath);
9773 Py_BEGIN_ALLOW_THREADS
9774 res = mkdirat(dirfd, path, mode);
9775 Py_END_ALLOW_THREADS
9776 Py_DECREF(opath);
9777 if (res < 0)
9778 return posix_error();
9779 Py_RETURN_NONE;
9780}
9781#endif
9782
9783#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
9784PyDoc_STRVAR(posix_mknodat__doc__,
9785"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
9786Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
9787If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9788is interpreted relative to the current working directory.");
9789
9790static PyObject *
9791posix_mknodat(PyObject *self, PyObject *args)
9792{
9793 PyObject *opath;
9794 char *filename;
9795 int mode = 0600;
9796 int device = 0;
9797 int res, dirfd;
9798 if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
9799 PyUnicode_FSConverter, &opath, &mode, &device))
9800 return NULL;
9801 filename = PyBytes_AS_STRING(opath);
9802 Py_BEGIN_ALLOW_THREADS
9803 res = mknodat(dirfd, filename, mode, device);
9804 Py_END_ALLOW_THREADS
9805 Py_DECREF(opath);
9806 if (res < 0)
9807 return posix_error();
9808 Py_RETURN_NONE;
9809}
9810#endif
9811
9812#ifdef HAVE_OPENAT
9813PyDoc_STRVAR(posix_openat__doc__,
9814"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
9815Like open() but if path is relative, it is taken as relative to dirfd.\n\
9816If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9817is interpreted relative to the current working directory.");
9818
9819static PyObject *
9820posix_openat(PyObject *self, PyObject *args)
9821{
9822 PyObject *ofile;
9823 char *file;
9824 int flag, dirfd, fd;
9825 int mode = 0777;
9826
9827 if (!PyArg_ParseTuple(args, "iO&i|i:openat",
9828 &dirfd, PyUnicode_FSConverter, &ofile,
9829 &flag, &mode))
9830 return NULL;
9831 file = PyBytes_AsString(ofile);
9832 Py_BEGIN_ALLOW_THREADS
9833 fd = openat(dirfd, file, flag, mode);
9834 Py_END_ALLOW_THREADS
9835 Py_DECREF(ofile);
9836 if (fd < 0)
9837 return posix_error();
9838 return PyLong_FromLong((long)fd);
9839}
9840#endif
9841
9842#ifdef HAVE_READLINKAT
9843PyDoc_STRVAR(posix_readlinkat__doc__,
9844"readlinkat(dirfd, path) -> path\n\n\
9845Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
9846If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9847is interpreted relative to the current working directory.");
9848
9849static PyObject *
9850posix_readlinkat(PyObject *self, PyObject *args)
9851{
9852 PyObject *v, *opath;
9853 char buf[MAXPATHLEN];
9854 char *path;
9855 int n, dirfd;
9856 int arg_is_unicode = 0;
9857
9858 if (!PyArg_ParseTuple(args, "iO&:readlinkat",
9859 &dirfd, PyUnicode_FSConverter, &opath))
9860 return NULL;
9861 path = PyBytes_AsString(opath);
9862 v = PySequence_GetItem(args, 1);
9863 if (v == NULL) {
9864 Py_DECREF(opath);
9865 return NULL;
9866 }
9867
9868 if (PyUnicode_Check(v)) {
9869 arg_is_unicode = 1;
9870 }
9871 Py_DECREF(v);
9872
9873 Py_BEGIN_ALLOW_THREADS
9874 n = readlinkat(dirfd, path, buf, (int) sizeof buf);
9875 Py_END_ALLOW_THREADS
9876 Py_DECREF(opath);
9877 if (n < 0)
9878 return posix_error();
9879
9880 if (arg_is_unicode)
9881 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
9882 else
9883 return PyBytes_FromStringAndSize(buf, n);
9884}
9885#endif /* HAVE_READLINKAT */
9886
9887#ifdef HAVE_RENAMEAT
9888PyDoc_STRVAR(posix_renameat__doc__,
9889"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
9890Like rename() but if oldpath is relative, it is taken as relative to\n\
9891olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
9892If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
9893oldpath is interpreted relative to the current working directory. This\n\
9894also applies for newpath.");
9895
9896static PyObject *
9897posix_renameat(PyObject *self, PyObject *args)
9898{
9899 int res;
9900 PyObject *opathold, *opathnew;
9901 char *opath, *npath;
9902 int oldfd, newfd;
9903
9904 if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
9905 &oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
9906 return NULL;
9907 opath = PyBytes_AsString(opathold);
9908 npath = PyBytes_AsString(opathnew);
9909 Py_BEGIN_ALLOW_THREADS
9910 res = renameat(oldfd, opath, newfd, npath);
9911 Py_END_ALLOW_THREADS
9912 Py_DECREF(opathold);
9913 Py_DECREF(opathnew);
9914 if (res < 0)
9915 return posix_error();
9916 Py_RETURN_NONE;
9917}
9918#endif
9919
9920#if HAVE_SYMLINKAT
9921PyDoc_STRVAR(posix_symlinkat__doc__,
9922"symlinkat(src, dstfd, dst)\n\n\
9923Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
9924If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
9925is interpreted relative to the current working directory.");
9926
9927static PyObject *
9928posix_symlinkat(PyObject *self, PyObject *args)
9929{
9930 int res, dstfd;
9931 PyObject *osrc, *odst;
9932 char *src, *dst;
9933
9934 if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
9935 PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
9936 return NULL;
9937 src = PyBytes_AsString(osrc);
9938 dst = PyBytes_AsString(odst);
9939 Py_BEGIN_ALLOW_THREADS
9940 res = symlinkat(src, dstfd, dst);
9941 Py_END_ALLOW_THREADS
9942 Py_DECREF(osrc);
9943 Py_DECREF(odst);
9944 if (res < 0)
9945 return posix_error();
9946 Py_RETURN_NONE;
9947}
9948#endif /* HAVE_SYMLINKAT */
9949
9950#ifdef HAVE_UNLINKAT
9951PyDoc_STRVAR(posix_unlinkat__doc__,
9952"unlinkat(dirfd, path, flags=0)\n\n\
9953Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
9954flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
9955specified, unlinkat() behaves like rmdir().\n\
9956If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9957is interpreted relative to the current working directory.");
9958
9959static PyObject *
9960posix_unlinkat(PyObject *self, PyObject *args)
9961{
9962 int dirfd, res, flags = 0;
9963 PyObject *opath;
9964 char *path;
9965
9966 if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
9967 &dirfd, PyUnicode_FSConverter, &opath, &flags))
9968 return NULL;
9969 path = PyBytes_AsString(opath);
9970 Py_BEGIN_ALLOW_THREADS
9971 res = unlinkat(dirfd, path, flags);
9972 Py_END_ALLOW_THREADS
9973 Py_DECREF(opath);
9974 if (res < 0)
9975 return posix_error();
9976 Py_RETURN_NONE;
9977}
9978#endif
9979
9980#ifdef HAVE_UTIMENSAT
9981PyDoc_STRVAR(posix_utimensat__doc__,
Brian Curtin569b4942011-11-07 16:09:20 -06009982"utimensat(dirfd, path[, atime=(atime_sec, atime_nsec),\n\
9983 mtime=(mtime_sec, mtime_nsec), flags=0])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009984utimensat(dirfd, path, None, None, flags)\n\n\
9985Updates the timestamps of a file with nanosecond precision. If path is\n\
9986relative, it is taken as relative to dirfd.\n\
Brian Curtin569b4942011-11-07 16:09:20 -06009987If atime and mtime are both None, which is the default, set atime and\n\
9988mtime to the current time.\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009989flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9990If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9991is interpreted relative to the current working directory.\n\
9992If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
9993current time.\n\
9994If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
9995
9996static PyObject *
Brian Curtin569b4942011-11-07 16:09:20 -06009997posix_utimensat(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009998{
9999 PyObject *opath;
10000 char *path;
10001 int res, dirfd, flags = 0;
Brian Curtin569b4942011-11-07 16:09:20 -060010002 PyObject *atime = Py_None;
10003 PyObject *mtime = Py_None;
10004
10005 static char *kwlist[] = {"dirfd", "path", "atime", "mtime", "flags", NULL};
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010006
10007 struct timespec buf[2];
10008
Brian Curtin569b4942011-11-07 16:09:20 -060010009 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&|OOi:utimensat", kwlist,
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010010 &dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
10011 return NULL;
10012 path = PyBytes_AsString(opath);
10013 if (atime == Py_None && mtime == Py_None) {
10014 /* optional time values not given */
10015 Py_BEGIN_ALLOW_THREADS
10016 res = utimensat(dirfd, path, NULL, flags);
10017 Py_END_ALLOW_THREADS
10018 }
10019 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
10020 PyErr_SetString(PyExc_TypeError,
10021 "utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
10022 Py_DECREF(opath);
10023 return NULL;
10024 }
10025 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
10026 PyErr_SetString(PyExc_TypeError,
10027 "utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
10028 Py_DECREF(opath);
10029 return NULL;
10030 }
10031 else {
10032 if (!PyArg_ParseTuple(atime, "ll:utimensat",
10033 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
10034 Py_DECREF(opath);
10035 return NULL;
10036 }
10037 if (!PyArg_ParseTuple(mtime, "ll:utimensat",
10038 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
10039 Py_DECREF(opath);
10040 return NULL;
10041 }
10042 Py_BEGIN_ALLOW_THREADS
10043 res = utimensat(dirfd, path, buf, flags);
10044 Py_END_ALLOW_THREADS
10045 }
10046 Py_DECREF(opath);
10047 if (res < 0) {
10048 return posix_error();
10049 }
10050 Py_RETURN_NONE;
10051}
10052#endif
10053
10054#ifdef HAVE_MKFIFOAT
10055PyDoc_STRVAR(posix_mkfifoat__doc__,
10056"mkfifoat(dirfd, path, mode=0o666)\n\n\
10057Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
10058If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10059is interpreted relative to the current working directory.");
10060
10061static PyObject *
10062posix_mkfifoat(PyObject *self, PyObject *args)
10063{
10064 PyObject *opath;
10065 char *filename;
10066 int mode = 0666;
10067 int res, dirfd;
10068 if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
10069 &dirfd, PyUnicode_FSConverter, &opath, &mode))
10070 return NULL;
10071 filename = PyBytes_AS_STRING(opath);
10072 Py_BEGIN_ALLOW_THREADS
10073 res = mkfifoat(dirfd, filename, mode);
10074 Py_END_ALLOW_THREADS
10075 Py_DECREF(opath);
10076 if (res < 0)
10077 return posix_error();
10078 Py_RETURN_NONE;
10079}
10080#endif
10081
Benjamin Peterson9428d532011-09-14 11:45:52 -040010082#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010083
10084static int
10085try_getxattr(const char *path, const char *name,
10086 ssize_t (*get)(const char *, const char *, void *, size_t),
10087 Py_ssize_t buf_size, PyObject **res)
10088{
10089 PyObject *value;
10090 Py_ssize_t len;
10091
10092 assert(buf_size <= XATTR_SIZE_MAX);
10093 value = PyBytes_FromStringAndSize(NULL, buf_size);
10094 if (!value)
10095 return 0;
10096 Py_BEGIN_ALLOW_THREADS;
10097 len = get(path, name, PyBytes_AS_STRING(value), buf_size);
10098 Py_END_ALLOW_THREADS;
10099 if (len < 0) {
10100 Py_DECREF(value);
10101 if (errno == ERANGE) {
10102 value = NULL;
10103 }
10104 else {
10105 posix_error();
10106 return 0;
10107 }
10108 }
10109 else if (len != buf_size) {
10110 /* Can only shrink. */
10111 _PyBytes_Resize(&value, len);
10112 }
10113 *res = value;
10114 return 1;
10115}
10116
10117static PyObject *
10118getxattr_common(const char *path, PyObject *name_obj,
10119 ssize_t (*get)(const char *, const char *, void *, size_t))
10120{
10121 PyObject *value;
10122 const char *name = PyBytes_AS_STRING(name_obj);
10123
10124 /* Try a small value first. */
10125 if (!try_getxattr(path, name, get, 128, &value))
10126 return NULL;
10127 if (value)
10128 return value;
10129 /* Now the maximum possible one. */
10130 if (!try_getxattr(path, name, get, XATTR_SIZE_MAX, &value))
10131 return NULL;
10132 assert(value);
10133 return value;
10134}
10135
10136PyDoc_STRVAR(posix_getxattr__doc__,
10137"getxattr(path, attr) -> value\n\n\
10138Return the value of extended attribute *name* on *path*.");
10139
10140static PyObject *
10141posix_getxattr(PyObject *self, PyObject *args)
10142{
10143 PyObject *path, *res, *name;
10144
10145 if (!PyArg_ParseTuple(args, "O&O&:getxattr", PyUnicode_FSConverter, &path,
10146 PyUnicode_FSConverter, &name))
10147 return NULL;
10148 res = getxattr_common(PyBytes_AS_STRING(path), name, getxattr);
10149 Py_DECREF(path);
10150 Py_DECREF(name);
10151 return res;
10152}
10153
10154PyDoc_STRVAR(posix_lgetxattr__doc__,
10155"lgetxattr(path, attr) -> value\n\n\
10156Like getxattr but don't follow symlinks.");
10157
10158static PyObject *
10159posix_lgetxattr(PyObject *self, PyObject *args)
10160{
10161 PyObject *path, *res, *name;
10162
10163 if (!PyArg_ParseTuple(args, "O&O&:lgetxattr", PyUnicode_FSConverter, &path,
10164 PyUnicode_FSConverter, &name))
10165 return NULL;
10166 res = getxattr_common(PyBytes_AS_STRING(path), name, lgetxattr);
10167 Py_DECREF(path);
10168 Py_DECREF(name);
10169 return res;
10170}
10171
10172static ssize_t
10173wrap_fgetxattr(const char *path, const char *name, void *value, size_t size)
10174{
10175 /* Hack to share code. */
10176 return fgetxattr((int)(Py_uintptr_t)path, name, value, size);
10177}
10178
10179PyDoc_STRVAR(posix_fgetxattr__doc__,
10180"fgetxattr(fd, attr) -> value\n\n\
10181Like getxattr but operate on a fd instead of a path.");
10182
10183static PyObject *
10184posix_fgetxattr(PyObject *self, PyObject *args)
10185{
10186 PyObject *res, *name;
10187 int fd;
10188
10189 if (!PyArg_ParseTuple(args, "iO&:fgetxattr", &fd, PyUnicode_FSConverter, &name))
10190 return NULL;
10191 res = getxattr_common((const char *)(Py_uintptr_t)fd, name, wrap_fgetxattr);
10192 Py_DECREF(name);
10193 return res;
10194}
10195
10196PyDoc_STRVAR(posix_setxattr__doc__,
10197"setxattr(path, attr, value, flags=0)\n\n\
10198Set extended attribute *attr* on *path* to *value*.");
10199
10200static PyObject *
10201posix_setxattr(PyObject *self, PyObject *args)
10202{
10203 PyObject *path, *name;
10204 Py_buffer data;
10205 int flags = 0, err;
10206
10207 if (!PyArg_ParseTuple(args, "O&O&y*|i:setxattr", PyUnicode_FSConverter,
10208 &path, PyUnicode_FSConverter, &name, &data, &flags))
10209 return NULL;
10210 Py_BEGIN_ALLOW_THREADS;
10211 err = setxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10212 data.buf, data.len, flags);
10213 Py_END_ALLOW_THREADS;
10214 Py_DECREF(path);
10215 Py_DECREF(name);
10216 PyBuffer_Release(&data);
10217 if (err)
10218 return posix_error();
10219 Py_RETURN_NONE;
10220}
10221
10222PyDoc_STRVAR(posix_lsetxattr__doc__,
10223"lsetxattr(path, attr, value, flags=0)\n\n\
10224Like setxattr but don't follow symlinks.");
10225
10226static PyObject *
10227posix_lsetxattr(PyObject *self, PyObject *args)
10228{
10229 PyObject *path, *name;
10230 Py_buffer data;
10231 int flags = 0, err;
10232
10233 if (!PyArg_ParseTuple(args, "O&O&y*|i:lsetxattr", PyUnicode_FSConverter,
10234 &path, PyUnicode_FSConverter, &name, &data, &flags))
10235 return NULL;
10236 Py_BEGIN_ALLOW_THREADS;
10237 err = lsetxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10238 data.buf, data.len, flags);
10239 Py_END_ALLOW_THREADS;
10240 Py_DECREF(path);
10241 Py_DECREF(name);
10242 PyBuffer_Release(&data);
10243 if (err)
10244 return posix_error();
10245 Py_RETURN_NONE;
10246}
10247
10248PyDoc_STRVAR(posix_fsetxattr__doc__,
10249"fsetxattr(fd, attr, value, flags=0)\n\n\
10250Like setxattr but operates on *fd* instead of a path.");
10251
10252static PyObject *
10253posix_fsetxattr(PyObject *self, PyObject *args)
10254{
10255 Py_buffer data;
10256 const char *name;
10257 int fd, flags = 0, err;
10258
10259 if (!PyArg_ParseTuple(args, "iO&y*|i:fsetxattr", &fd, PyUnicode_FSConverter,
10260 &name, &data, &flags))
10261 return NULL;
10262 Py_BEGIN_ALLOW_THREADS;
10263 err = fsetxattr(fd, PyBytes_AS_STRING(name), data.buf, data.len, flags);
10264 Py_END_ALLOW_THREADS;
10265 Py_DECREF(name);
10266 PyBuffer_Release(&data);
10267 if (err)
10268 return posix_error();
10269 Py_RETURN_NONE;
10270}
10271
10272PyDoc_STRVAR(posix_removexattr__doc__,
10273"removexattr(path, attr)\n\n\
10274Remove extended attribute *attr* on *path*.");
10275
10276static PyObject *
10277posix_removexattr(PyObject *self, PyObject *args)
10278{
10279 PyObject *path, *name;
10280 int err;
10281
10282 if (!PyArg_ParseTuple(args, "O&O&:removexattr", PyUnicode_FSConverter, &path,
10283 PyUnicode_FSConverter, &name))
10284 return NULL;
10285 Py_BEGIN_ALLOW_THREADS;
10286 err = removexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10287 Py_END_ALLOW_THREADS;
10288 Py_DECREF(path);
10289 Py_DECREF(name);
10290 if (err)
10291 return posix_error();
10292 Py_RETURN_NONE;
10293}
10294
10295PyDoc_STRVAR(posix_lremovexattr__doc__,
10296"lremovexattr(path, attr)\n\n\
10297Like removexattr but don't follow symlinks.");
10298
10299static PyObject *
10300posix_lremovexattr(PyObject *self, PyObject *args)
10301{
10302 PyObject *path, *name;
10303 int err;
10304
10305 if (!PyArg_ParseTuple(args, "O&O&:lremovexattr", PyUnicode_FSConverter, &path,
10306 PyUnicode_FSConverter, &name))
10307 return NULL;
10308 Py_BEGIN_ALLOW_THREADS;
10309 err = lremovexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10310 Py_END_ALLOW_THREADS;
10311 Py_DECREF(path);
10312 Py_DECREF(name);
10313 if (err)
10314 return posix_error();
10315 Py_RETURN_NONE;
10316}
10317
10318PyDoc_STRVAR(posix_fremovexattr__doc__,
10319"fremovexattr(fd, attr)\n\n\
10320Like removexattr but operates on a file descriptor.");
10321
10322static PyObject *
10323posix_fremovexattr(PyObject *self, PyObject *args)
10324{
10325 PyObject *name;
10326 int fd, err;
10327
10328 if (!PyArg_ParseTuple(args, "iO&:fremovexattr", &fd,
10329 PyUnicode_FSConverter, &name))
10330 return NULL;
10331 Py_BEGIN_ALLOW_THREADS;
10332 err = fremovexattr(fd, PyBytes_AS_STRING(name));
10333 Py_END_ALLOW_THREADS;
10334 Py_DECREF(name);
10335 if (err)
10336 return posix_error();
10337 Py_RETURN_NONE;
10338}
10339
10340static Py_ssize_t
10341try_listxattr(const char *path, ssize_t (*list)(const char *, char *, size_t),
10342 Py_ssize_t buf_size, char **buf)
10343{
10344 Py_ssize_t len;
10345
10346 *buf = PyMem_MALLOC(buf_size);
10347 if (!*buf) {
10348 PyErr_NoMemory();
10349 return -1;
10350 }
10351 Py_BEGIN_ALLOW_THREADS;
10352 len = list(path, *buf, buf_size);
10353 Py_END_ALLOW_THREADS;
10354 if (len < 0) {
10355 PyMem_FREE(*buf);
10356 if (errno != ERANGE)
10357 posix_error();
10358 return -1;
10359 }
10360 return len;
10361}
10362
10363static PyObject *
10364listxattr_common(const char *path, ssize_t (*list)(const char *, char *, size_t))
10365{
10366 PyObject *res, *attr;
10367 Py_ssize_t len, err, start, i;
10368 char *buf;
10369
10370 len = try_listxattr(path, list, 256, &buf);
10371 if (len < 0) {
10372 if (PyErr_Occurred())
10373 return NULL;
10374 len = try_listxattr(path, list, XATTR_LIST_MAX, &buf);
10375 if (len < 0)
10376 return NULL;
10377 }
10378 res = PyList_New(0);
10379 if (!res) {
10380 PyMem_FREE(buf);
10381 return NULL;
10382 }
10383 for (start = i = 0; i < len; i++) {
10384 if (!buf[i]) {
10385 attr = PyUnicode_DecodeFSDefaultAndSize(&buf[start], i - start);
10386 if (!attr) {
10387 Py_DECREF(res);
10388 PyMem_FREE(buf);
10389 return NULL;
10390 }
10391 err = PyList_Append(res, attr);
10392 Py_DECREF(attr);
10393 if (err) {
10394 Py_DECREF(res);
10395 PyMem_FREE(buf);
10396 return NULL;
10397 }
10398 start = i + 1;
10399 }
10400 }
10401 PyMem_FREE(buf);
10402 return res;
10403}
10404
10405PyDoc_STRVAR(posix_listxattr__doc__,
10406"listxattr(path)\n\n\
10407Return a list of extended attributes on *path*.");
10408
10409static PyObject *
10410posix_listxattr(PyObject *self, PyObject *args)
10411{
10412 PyObject *path, *res;
10413
10414 if (!PyArg_ParseTuple(args, "O&:listxattr", PyUnicode_FSConverter, &path))
10415 return NULL;
10416 res = listxattr_common(PyBytes_AS_STRING(path), listxattr);
10417 Py_DECREF(path);
10418 return res;
10419}
10420
10421PyDoc_STRVAR(posix_llistxattr__doc__,
10422"llistxattr(path)\n\n\
10423Like listxattr but don't follow symlinks..");
10424
10425static PyObject *
10426posix_llistxattr(PyObject *self, PyObject *args)
10427{
10428 PyObject *path, *res;
10429
10430 if (!PyArg_ParseTuple(args, "O&:llistxattr", PyUnicode_FSConverter, &path))
10431 return NULL;
10432 res = listxattr_common(PyBytes_AS_STRING(path), llistxattr);
10433 Py_DECREF(path);
10434 return res;
10435}
10436
10437static ssize_t
10438wrap_flistxattr(const char *path, char *buf, size_t len)
10439{
10440 /* Hack to share code. */
10441 return flistxattr((int)(Py_uintptr_t)path, buf, len);
10442}
10443
10444PyDoc_STRVAR(posix_flistxattr__doc__,
10445"flistxattr(path)\n\n\
10446Like flistxattr but operates on a file descriptor.");
10447
10448static PyObject *
10449posix_flistxattr(PyObject *self, PyObject *args)
10450{
10451 long fd;
10452
10453 if (!PyArg_ParseTuple(args, "i:flistxattr", &fd))
10454 return NULL;
10455 return listxattr_common((const char *)(Py_uintptr_t)fd, wrap_flistxattr);
10456}
10457
Benjamin Peterson9428d532011-09-14 11:45:52 -040010458#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010459
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010460
Georg Brandl2fb477c2012-02-21 00:33:36 +010010461PyDoc_STRVAR(posix_urandom__doc__,
10462"urandom(n) -> str\n\n\
10463Return n random bytes suitable for cryptographic use.");
10464
10465static PyObject *
10466posix_urandom(PyObject *self, PyObject *args)
10467{
10468 Py_ssize_t size;
10469 PyObject *result;
10470 int ret;
10471
10472 /* Read arguments */
10473 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10474 return NULL;
10475 if (size < 0)
10476 return PyErr_Format(PyExc_ValueError,
10477 "negative argument not allowed");
10478 result = PyBytes_FromStringAndSize(NULL, size);
10479 if (result == NULL)
10480 return NULL;
10481
10482 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10483 PyBytes_GET_SIZE(result));
10484 if (ret == -1) {
10485 Py_DECREF(result);
10486 return NULL;
10487 }
10488 return result;
10489}
10490
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010491/* Terminal size querying */
10492
10493static PyTypeObject TerminalSizeType;
10494
10495PyDoc_STRVAR(TerminalSize_docstring,
10496 "A tuple of (columns, lines) for holding terminal window size");
10497
10498static PyStructSequence_Field TerminalSize_fields[] = {
10499 {"columns", "width of the terminal window in characters"},
10500 {"lines", "height of the terminal window in characters"},
10501 {NULL, NULL}
10502};
10503
10504static PyStructSequence_Desc TerminalSize_desc = {
10505 "os.terminal_size",
10506 TerminalSize_docstring,
10507 TerminalSize_fields,
10508 2,
10509};
10510
10511#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10512PyDoc_STRVAR(termsize__doc__,
10513 "Return the size of the terminal window as (columns, lines).\n" \
10514 "\n" \
10515 "The optional argument fd (default standard output) specifies\n" \
10516 "which file descriptor should be queried.\n" \
10517 "\n" \
10518 "If the file descriptor is not connected to a terminal, an OSError\n" \
10519 "is thrown.\n" \
10520 "\n" \
10521 "This function will only be defined if an implementation is\n" \
10522 "available for this system.\n" \
10523 "\n" \
10524 "shutil.get_terminal_size is the high-level function which should \n" \
10525 "normally be used, os.get_terminal_size is the low-level implementation.");
10526
10527static PyObject*
10528get_terminal_size(PyObject *self, PyObject *args)
10529{
10530 int columns, lines;
10531 PyObject *termsize;
10532
10533 int fd = fileno(stdout);
10534 /* Under some conditions stdout may not be connected and
10535 * fileno(stdout) may point to an invalid file descriptor. For example
10536 * GUI apps don't have valid standard streams by default.
10537 *
10538 * If this happens, and the optional fd argument is not present,
10539 * the ioctl below will fail returning EBADF. This is what we want.
10540 */
10541
10542 if (!PyArg_ParseTuple(args, "|i", &fd))
10543 return NULL;
10544
10545#ifdef TERMSIZE_USE_IOCTL
10546 {
10547 struct winsize w;
10548 if (ioctl(fd, TIOCGWINSZ, &w))
10549 return PyErr_SetFromErrno(PyExc_OSError);
10550 columns = w.ws_col;
10551 lines = w.ws_row;
10552 }
10553#endif /* TERMSIZE_USE_IOCTL */
10554
10555#ifdef TERMSIZE_USE_CONIO
10556 {
10557 DWORD nhandle;
10558 HANDLE handle;
10559 CONSOLE_SCREEN_BUFFER_INFO csbi;
10560 switch (fd) {
10561 case 0: nhandle = STD_INPUT_HANDLE;
10562 break;
10563 case 1: nhandle = STD_OUTPUT_HANDLE;
10564 break;
10565 case 2: nhandle = STD_ERROR_HANDLE;
10566 break;
10567 default:
10568 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10569 }
10570 handle = GetStdHandle(nhandle);
10571 if (handle == NULL)
10572 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10573 if (handle == INVALID_HANDLE_VALUE)
10574 return PyErr_SetFromWindowsErr(0);
10575
10576 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10577 return PyErr_SetFromWindowsErr(0);
10578
10579 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10580 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10581 }
10582#endif /* TERMSIZE_USE_CONIO */
10583
10584 termsize = PyStructSequence_New(&TerminalSizeType);
10585 if (termsize == NULL)
10586 return NULL;
10587 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10588 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10589 if (PyErr_Occurred()) {
10590 Py_DECREF(termsize);
10591 return NULL;
10592 }
10593 return termsize;
10594}
10595#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10596
10597
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010598static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010600#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010602#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010604#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010606#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010608#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010609 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010610#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010611#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010612 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010613#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010614#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010615 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010616#endif /* HAVE_LCHMOD */
10617#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010618 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010619#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010620#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010622#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010623#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010624 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010625#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010626#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010627 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010628#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010629#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010631#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010632#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010633 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10634 METH_NOARGS, posix_getcwd__doc__},
10635 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10636 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010637#endif
10638#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010639 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010640#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +000010641 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010642#ifdef HAVE_FDOPENDIR
Charles-François Natali77940902012-02-06 19:54:48 +010010643 {"flistdir", posix_flistdir, METH_VARARGS, posix_flistdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010644#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010645 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010647#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010649#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010650#ifdef HAVE_GETPRIORITY
10651 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10652#endif /* HAVE_GETPRIORITY */
10653#ifdef HAVE_SETPRIORITY
10654 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10655#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010656#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010657 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010658#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010659#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010660 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010661#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010662 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
Antoine Pitrouf3b2d882012-01-30 22:08:52 +010010663 {"replace", posix_replace, METH_VARARGS, posix_replace__doc__},
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010664 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
Victor Stinner4195b5c2012-02-08 23:03:19 +010010665 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +000010667#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +000010668 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010669#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +000010670#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010671 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +000010672 win_symlink__doc__},
10673#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010674#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010676#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010677 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010678#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010680#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
10682 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010683 {"utime", (PyCFunction)posix_utime,
10684 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010685#ifdef HAVE_FUTIMES
Larry Hastings76ad59b2012-05-03 00:30:07 -070010686 {"futimes", (PyCFunction)posix_futimes,
10687 METH_VARARGS | METH_KEYWORDS, posix_futimes__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010688#endif
10689#ifdef HAVE_LUTIMES
Larry Hastings76ad59b2012-05-03 00:30:07 -070010690 {"lutimes", (PyCFunction)posix_lutimes,
10691 METH_VARARGS | METH_KEYWORDS, posix_lutimes__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010692#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010693#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010694 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010695#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010697#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010698 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
10699 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010700#endif /* HAVE_EXECV */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010701#ifdef HAVE_FEXECVE
10702 {"fexecve", posix_fexecve, METH_VARARGS, posix_fexecve__doc__},
10703#endif
Guido van Rossuma1065681999-01-25 23:20:23 +000010704#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10706 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010707#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10709 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010710#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010711#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010712#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010713 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010714#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010715#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010716 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010717#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010718#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010719#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010720 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10721 {"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 +020010722#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010723#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010724 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010725#endif
10726#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010727 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010728#endif
10729#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010730 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010731#endif
10732#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010733 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010734#endif
10735#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010736 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010737#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010738 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010739#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010740 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10741 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10742#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010743#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010744#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010745 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010746#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010747#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010749#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010750#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010752#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010753#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010754 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010755#endif /* HAVE_GETEUID */
10756#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010757 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010758#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010759#ifdef HAVE_GETGROUPLIST
10760 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10761#endif
Fred Drakec9680921999-12-13 16:37:25 +000010762#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010764#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010766#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010767 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010768#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010769#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010770 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010771#endif /* HAVE_GETPPID */
10772#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010773 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010774#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010775#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010776 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010777#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010778#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010779 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010780#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010781#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010782 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010783#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010784#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010785 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010786#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010787#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010788 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10789 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +000010790 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010791#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010792#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010794#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010795#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010797#endif /* HAVE_SETEUID */
10798#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010800#endif /* HAVE_SETEGID */
10801#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010803#endif /* HAVE_SETREUID */
10804#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010806#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010807#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010809#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010810#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010812#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010813#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010815#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010816#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010818#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010819#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010821#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010822#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010824#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010825#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010826 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010827#endif /* HAVE_WAIT3 */
10828#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010829 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010830#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010831#if defined(HAVE_WAITID) && !defined(__APPLE__)
10832 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10833#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010834#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010836#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010837#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010839#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010840#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010842#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010843#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010845#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010846#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010848#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010849#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010851#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"open", posix_open, METH_VARARGS, posix_open__doc__},
10853 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10854 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10855 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10856 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10857 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010858#ifdef HAVE_LOCKF
10859 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10860#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10862 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010863#ifdef HAVE_READV
10864 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10865#endif
10866#ifdef HAVE_PREAD
10867 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10868#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010870#ifdef HAVE_WRITEV
10871 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10872#endif
10873#ifdef HAVE_PWRITE
10874 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10875#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010876#ifdef HAVE_SENDFILE
10877 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10878 posix_sendfile__doc__},
10879#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010880 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010882#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010884#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010885#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010886 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010887#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010888#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010890#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010891#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +000010892 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010893#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010894#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10896 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10897 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010898#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010899#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010901#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010902#ifdef HAVE_TRUNCATE
10903 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
10904#endif
10905#ifdef HAVE_POSIX_FALLOCATE
10906 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10907#endif
10908#ifdef HAVE_POSIX_FADVISE
10909 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10910#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010911#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010913#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010914#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010916#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010917 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010918#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010919 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010920#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010921#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010923#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010924#ifdef HAVE_SYNC
10925 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10926#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010927#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010929#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010930#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010931#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010932 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010933#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010934#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010935 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010936#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010937#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010939#endif /* WIFSTOPPED */
10940#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010942#endif /* WIFSIGNALED */
10943#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010945#endif /* WIFEXITED */
10946#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010948#endif /* WEXITSTATUS */
10949#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010950 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010951#endif /* WTERMSIG */
10952#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010953 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010954#endif /* WSTOPSIG */
10955#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010956#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010957 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010958#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010959#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010960 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010961#endif
Fred Drakec9680921999-12-13 16:37:25 +000010962#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010963 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010964#endif
10965#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010966 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010967#endif
10968#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010969 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010970#endif
10971#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010972 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010973#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010975#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010977 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010978 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010979 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010980 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010981#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010982#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010984#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010985 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010986#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010987 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010988#endif
10989#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010991#endif
10992#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010993 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010994#endif
10995#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010996 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010997#endif
10998
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010999/* posix *at family of functions */
11000#ifdef HAVE_FACCESSAT
11001 {"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
11002#endif
11003#ifdef HAVE_FCHMODAT
11004 {"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
11005#endif /* HAVE_FCHMODAT */
11006#ifdef HAVE_FCHOWNAT
11007 {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
11008#endif /* HAVE_FCHOWNAT */
11009#ifdef HAVE_FSTATAT
Victor Stinner4195b5c2012-02-08 23:03:19 +010011010 {"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__},
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011011#endif
11012#ifdef HAVE_FUTIMESAT
11013 {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
11014#endif
11015#ifdef HAVE_LINKAT
11016 {"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
11017#endif /* HAVE_LINKAT */
11018#ifdef HAVE_MKDIRAT
11019 {"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
11020#endif
11021#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
11022 {"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
11023#endif
11024#ifdef HAVE_OPENAT
11025 {"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
11026#endif
11027#ifdef HAVE_READLINKAT
11028 {"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
11029#endif /* HAVE_READLINKAT */
11030#ifdef HAVE_RENAMEAT
11031 {"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
11032#endif
11033#if HAVE_SYMLINKAT
11034 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
11035#endif /* HAVE_SYMLINKAT */
11036#ifdef HAVE_UNLINKAT
11037 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
11038#endif
11039#ifdef HAVE_UTIMENSAT
Jesus Cead03a4912011-11-08 17:28:04 +010011040 {"utimensat", (PyCFunction)posix_utimensat,
11041 METH_VARARGS | METH_KEYWORDS,
Brian Curtin569b4942011-11-07 16:09:20 -060011042 posix_utimensat__doc__},
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011043#endif
11044#ifdef HAVE_MKFIFOAT
11045 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
11046#endif
Benjamin Peterson9428d532011-09-14 11:45:52 -040011047#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011048 {"setxattr", posix_setxattr, METH_VARARGS, posix_setxattr__doc__},
11049 {"lsetxattr", posix_lsetxattr, METH_VARARGS, posix_lsetxattr__doc__},
11050 {"fsetxattr", posix_fsetxattr, METH_VARARGS, posix_fsetxattr__doc__},
11051 {"getxattr", posix_getxattr, METH_VARARGS, posix_getxattr__doc__},
11052 {"lgetxattr", posix_lgetxattr, METH_VARARGS, posix_lgetxattr__doc__},
11053 {"fgetxattr", posix_fgetxattr, METH_VARARGS, posix_fgetxattr__doc__},
11054 {"removexattr", posix_removexattr, METH_VARARGS, posix_removexattr__doc__},
11055 {"lremovexattr", posix_lremovexattr, METH_VARARGS, posix_lremovexattr__doc__},
11056 {"fremovexattr", posix_fremovexattr, METH_VARARGS, posix_fremovexattr__doc__},
11057 {"listxattr", posix_listxattr, METH_VARARGS, posix_listxattr__doc__},
11058 {"llistxattr", posix_llistxattr, METH_VARARGS, posix_llistxattr__doc__},
11059 {"flistxattr", posix_flistxattr, METH_VARARGS, posix_flistxattr__doc__},
11060#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011061#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11062 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11063#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011065};
11066
11067
Barry Warsaw4a342091996-12-19 23:50:02 +000011068static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011069ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011070{
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011072}
11073
Guido van Rossumd48f2521997-12-05 22:19:34 +000011074#if defined(PYOS_OS2)
11075/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011076static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011077{
11078 APIRET rc;
11079 ULONG values[QSV_MAX+1];
11080 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011081 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011082
11083 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011084 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011085 Py_END_ALLOW_THREADS
11086
11087 if (rc != NO_ERROR) {
11088 os2_error(rc);
11089 return -1;
11090 }
11091
Fred Drake4d1e64b2002-04-15 19:40:07 +000011092 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11093 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11094 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11095 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11096 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11097 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11098 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011099
11100 switch (values[QSV_VERSION_MINOR]) {
11101 case 0: ver = "2.00"; break;
11102 case 10: ver = "2.10"; break;
11103 case 11: ver = "2.11"; break;
11104 case 30: ver = "3.00"; break;
11105 case 40: ver = "4.00"; break;
11106 case 50: ver = "5.00"; break;
11107 default:
Tim Peters885d4572001-11-28 20:27:42 +000011108 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011110 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011111 ver = &tmp[0];
11112 }
11113
11114 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011115 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011116 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011117
11118 /* Add Indicator of Which Drive was Used to Boot the System */
11119 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11120 tmp[1] = ':';
11121 tmp[2] = '\0';
11122
Fred Drake4d1e64b2002-04-15 19:40:07 +000011123 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011124}
11125#endif
11126
Brian Curtin52173d42010-12-02 18:29:18 +000011127#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011128static int
Brian Curtin52173d42010-12-02 18:29:18 +000011129enable_symlink()
11130{
11131 HANDLE tok;
11132 TOKEN_PRIVILEGES tok_priv;
11133 LUID luid;
11134 int meth_idx = 0;
11135
11136 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011137 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011138
11139 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011140 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011141
11142 tok_priv.PrivilegeCount = 1;
11143 tok_priv.Privileges[0].Luid = luid;
11144 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11145
11146 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11147 sizeof(TOKEN_PRIVILEGES),
11148 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011149 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011150
Brian Curtin3b4499c2010-12-28 14:31:47 +000011151 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11152 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011153}
11154#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11155
Barry Warsaw4a342091996-12-19 23:50:02 +000011156static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011157all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011158{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011159#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011161#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011162#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011164#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011165#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011167#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011168#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011170#endif
Fred Drakec9680921999-12-13 16:37:25 +000011171#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011173#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011174#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011176#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011177#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011178 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011179#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011180#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011181 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011182#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011183#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011184 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011185#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011186#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011187 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011188#endif
11189#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011190 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011191#endif
11192#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011194#endif
11195#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011196 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011197#endif
11198#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011200#endif
11201#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011203#endif
11204#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011206#endif
11207#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011209#endif
11210#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011212#endif
11213#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011215#endif
11216#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011218#endif
11219#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011221#endif
11222#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011224#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011225#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011227#endif
11228#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011230#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011231#ifdef O_XATTR
11232 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11233#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011234#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011236#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011237#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011239#endif
11240#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011242#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011243#ifdef O_EXEC
11244 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11245#endif
11246#ifdef O_SEARCH
11247 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11248#endif
11249#ifdef O_TTY_INIT
11250 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11251#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011252#ifdef PRIO_PROCESS
11253 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11254#endif
11255#ifdef PRIO_PGRP
11256 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11257#endif
11258#ifdef PRIO_USER
11259 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11260#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011261#ifdef O_CLOEXEC
11262 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11263#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011264#ifdef O_ACCMODE
11265 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11266#endif
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011267/* posix - constants for *at functions */
11268#ifdef AT_SYMLINK_NOFOLLOW
11269 if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
11270#endif
11271#ifdef AT_EACCESS
11272 if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
11273#endif
11274#ifdef AT_FDCWD
11275 if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
11276#endif
11277#ifdef AT_REMOVEDIR
11278 if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
11279#endif
11280#ifdef AT_SYMLINK_FOLLOW
11281 if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
11282#endif
11283#ifdef UTIME_NOW
11284 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11285#endif
11286#ifdef UTIME_OMIT
11287 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11288#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011289
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011290
Tim Peters5aa91602002-01-30 05:46:57 +000011291/* MS Windows */
11292#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011293 /* Don't inherit in child processes. */
11294 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011295#endif
11296#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 /* Optimize for short life (keep in memory). */
11298 /* MS forgot to define this one with a non-underscore form too. */
11299 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011300#endif
11301#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011302 /* Automatically delete when last handle is closed. */
11303 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011304#endif
11305#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 /* Optimize for random access. */
11307 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011308#endif
11309#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 /* Optimize for sequential access. */
11311 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011312#endif
11313
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011314/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011315#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 /* Send a SIGIO signal whenever input or output
11317 becomes available on file descriptor */
11318 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011319#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011320#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011321 /* Direct disk access. */
11322 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011323#endif
11324#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 /* Must be a directory. */
11326 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011327#endif
11328#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 /* Do not follow links. */
11330 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011331#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011332#ifdef O_NOLINKS
11333 /* Fails if link count of the named file is greater than 1 */
11334 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11335#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011336#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 /* Do not update the access time. */
11338 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011339#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011340
Victor Stinner8c62be82010-05-06 00:08:46 +000011341 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011342#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011343 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011344#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011345#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011347#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011348#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011349 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011350#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011351#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011352 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011353#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011354#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011355 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011356#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011357#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011358 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011359#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011360#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011362#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011363#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011364 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011365#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011366#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011368#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011369#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011371#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011372#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011373 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011374#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011375#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011377#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011378#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011380#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011381#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011383#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011384#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011386#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011387#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011388 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011389#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011390#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011391 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011392#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011393
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011394 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011395#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011396 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011397#endif /* ST_RDONLY */
11398#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011399 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011400#endif /* ST_NOSUID */
11401
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011402 /* FreeBSD sendfile() constants */
11403#ifdef SF_NODISKIO
11404 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11405#endif
11406#ifdef SF_MNOWAIT
11407 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11408#endif
11409#ifdef SF_SYNC
11410 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11411#endif
11412
Ross Lagerwall7807c352011-03-17 20:20:30 +020011413 /* constants for posix_fadvise */
11414#ifdef POSIX_FADV_NORMAL
11415 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11416#endif
11417#ifdef POSIX_FADV_SEQUENTIAL
11418 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11419#endif
11420#ifdef POSIX_FADV_RANDOM
11421 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11422#endif
11423#ifdef POSIX_FADV_NOREUSE
11424 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11425#endif
11426#ifdef POSIX_FADV_WILLNEED
11427 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11428#endif
11429#ifdef POSIX_FADV_DONTNEED
11430 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11431#endif
11432
11433 /* constants for waitid */
11434#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11435 if (ins(d, "P_PID", (long)P_PID)) return -1;
11436 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11437 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11438#endif
11439#ifdef WEXITED
11440 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11441#endif
11442#ifdef WNOWAIT
11443 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11444#endif
11445#ifdef WSTOPPED
11446 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11447#endif
11448#ifdef CLD_EXITED
11449 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11450#endif
11451#ifdef CLD_DUMPED
11452 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11453#endif
11454#ifdef CLD_TRAPPED
11455 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11456#endif
11457#ifdef CLD_CONTINUED
11458 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11459#endif
11460
11461 /* constants for lockf */
11462#ifdef F_LOCK
11463 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11464#endif
11465#ifdef F_TLOCK
11466 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11467#endif
11468#ifdef F_ULOCK
11469 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11470#endif
11471#ifdef F_TEST
11472 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11473#endif
11474
11475 /* constants for futimens */
11476#ifdef UTIME_NOW
11477 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11478#endif
11479#ifdef UTIME_OMIT
11480 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11481#endif
11482
Guido van Rossum246bc171999-02-01 23:54:31 +000011483#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011484#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011485 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11486 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11487 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11488 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11489 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11490 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11491 if (ins(d, "P_PM", (long)P_PM)) return -1;
11492 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11493 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11494 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11495 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11496 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11497 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11498 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11499 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11500 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11501 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11502 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11503 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11504 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011505#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011506 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11507 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11508 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11509 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11510 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011511#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011512#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011513
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011514#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011515 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011516 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11517 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11518#ifdef SCHED_SPORADIC
11519 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11520#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011521#ifdef SCHED_BATCH
11522 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11523#endif
11524#ifdef SCHED_IDLE
11525 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11526#endif
11527#ifdef SCHED_RESET_ON_FORK
11528 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11529#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011530#ifdef SCHED_SYS
11531 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11532#endif
11533#ifdef SCHED_IA
11534 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11535#endif
11536#ifdef SCHED_FSS
11537 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11538#endif
11539#ifdef SCHED_FX
11540 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11541#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011542#endif
11543
Benjamin Peterson9428d532011-09-14 11:45:52 -040011544#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011545 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11546 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11547 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11548#endif
11549
Victor Stinner8b905bd2011-10-25 13:34:04 +020011550#ifdef RTLD_LAZY
11551 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11552#endif
11553#ifdef RTLD_NOW
11554 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11555#endif
11556#ifdef RTLD_GLOBAL
11557 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11558#endif
11559#ifdef RTLD_LOCAL
11560 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11561#endif
11562#ifdef RTLD_NODELETE
11563 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11564#endif
11565#ifdef RTLD_NOLOAD
11566 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11567#endif
11568#ifdef RTLD_DEEPBIND
11569 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11570#endif
11571
Guido van Rossumd48f2521997-12-05 22:19:34 +000011572#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011573 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011574#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011575 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011576}
11577
11578
Tim Peters5aa91602002-01-30 05:46:57 +000011579#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011580#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011581#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011582
11583#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011584#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011585#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011586
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011587#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011588#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011589#define MODNAME "posix"
11590#endif
11591
Martin v. Löwis1a214512008-06-11 05:26:20 +000011592static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011593 PyModuleDef_HEAD_INIT,
11594 MODNAME,
11595 posix__doc__,
11596 -1,
11597 posix_methods,
11598 NULL,
11599 NULL,
11600 NULL,
11601 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011602};
11603
11604
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011605PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011606INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011607{
Victor Stinner8c62be82010-05-06 00:08:46 +000011608 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +000011609
Brian Curtin52173d42010-12-02 18:29:18 +000011610#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011611 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011612#endif
11613
Victor Stinner8c62be82010-05-06 00:08:46 +000011614 m = PyModule_Create(&posixmodule);
11615 if (m == NULL)
11616 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011617
Victor Stinner8c62be82010-05-06 00:08:46 +000011618 /* Initialize environ dictionary */
11619 v = convertenviron();
11620 Py_XINCREF(v);
11621 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11622 return NULL;
11623 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011624
Victor Stinner8c62be82010-05-06 00:08:46 +000011625 if (all_ins(m))
11626 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011627
Victor Stinner8c62be82010-05-06 00:08:46 +000011628 if (setup_confname_tables(m))
11629 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011630
Victor Stinner8c62be82010-05-06 00:08:46 +000011631 Py_INCREF(PyExc_OSError);
11632 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011633
Benjamin Peterson2740af82011-08-02 17:41:34 -050011634#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011635 if (PyType_Ready(&cpu_set_type) < 0)
11636 return NULL;
11637 Py_INCREF(&cpu_set_type);
11638 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011639#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011640
Guido van Rossumb3d39562000-01-31 18:41:26 +000011641#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011642 if (posix_putenv_garbage == NULL)
11643 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011644#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011645
Victor Stinner8c62be82010-05-06 00:08:46 +000011646 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011647#if defined(HAVE_WAITID) && !defined(__APPLE__)
11648 waitid_result_desc.name = MODNAME ".waitid_result";
11649 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11650#endif
11651
Victor Stinner8c62be82010-05-06 00:08:46 +000011652 stat_result_desc.name = MODNAME ".stat_result";
11653 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11654 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11655 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11656 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11657 structseq_new = StatResultType.tp_new;
11658 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011659
Victor Stinner8c62be82010-05-06 00:08:46 +000011660 statvfs_result_desc.name = MODNAME ".statvfs_result";
11661 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011662#ifdef NEED_TICKS_PER_SECOND
11663# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011664 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011665# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011666 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011667# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011668 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011669# endif
11670#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011671
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011672#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011673 sched_param_desc.name = MODNAME ".sched_param";
11674 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11675 SchedParamType.tp_new = sched_param_new;
11676#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011677
11678 /* initialize TerminalSize_info */
11679 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
11680 Py_INCREF(&TerminalSizeType);
Victor Stinner8c62be82010-05-06 00:08:46 +000011681 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011682#if defined(HAVE_WAITID) && !defined(__APPLE__)
11683 Py_INCREF((PyObject*) &WaitidResultType);
11684 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11685#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011686 Py_INCREF((PyObject*) &StatResultType);
11687 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11688 Py_INCREF((PyObject*) &StatVFSResultType);
11689 PyModule_AddObject(m, "statvfs_result",
11690 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011691
11692#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011693 Py_INCREF(&SchedParamType);
11694 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011695#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011696 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011697
11698#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011699 /*
11700 * Step 2 of weak-linking support on Mac OS X.
11701 *
11702 * The code below removes functions that are not available on the
11703 * currently active platform.
11704 *
11705 * This block allow one to use a python binary that was build on
11706 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
11707 * OSX 10.4.
11708 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011709#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011710 if (fstatvfs == NULL) {
11711 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11712 return NULL;
11713 }
11714 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011715#endif /* HAVE_FSTATVFS */
11716
11717#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011718 if (statvfs == NULL) {
11719 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11720 return NULL;
11721 }
11722 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011723#endif /* HAVE_STATVFS */
11724
11725# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011726 if (lchown == NULL) {
11727 if (PyObject_DelAttrString(m, "lchown") == -1) {
11728 return NULL;
11729 }
11730 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011731#endif /* HAVE_LCHOWN */
11732
11733
11734#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011735
11736 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11737
Larry Hastings6fe20b32012-04-19 15:07:49 -070011738 billion = PyLong_FromLong(1000000000);
11739 if (!billion)
11740 return NULL;
11741
Victor Stinner8c62be82010-05-06 00:08:46 +000011742 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011743
Guido van Rossumb6775db1994-08-01 11:34:53 +000011744}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011745
11746#ifdef __cplusplus
11747}
11748#endif