blob: 2e65da2a5f6e9b11ee2831d2322d882b90a98de5 [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
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 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
Jesus Ceaab70e2a2012-10-05 01:48:08 +02009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Thomas Wouters477c8d52006-05-27 19:21:47 +000011#ifdef __APPLE__
12 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000013 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000014 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
15 * at the end of this file for more information.
16 */
17# pragma weak lchown
18# pragma weak statvfs
19# pragma weak fstatvfs
20
21#endif /* __APPLE__ */
22
Thomas Wouters68bc4f92006-03-01 01:05:10 +000023#define PY_SSIZE_T_CLEAN
24
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000025#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000026
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000027#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020028# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000029# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#endif /* defined(__VMS) */
31
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032#ifdef __cplusplus
33extern "C" {
34#endif
35
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000036PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000037"This module provides access to operating system functionality that is\n\
38standardized by the C Standard and the POSIX standard (a thinly\n\
39disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000040corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000042
Ross Lagerwall4d076da2011-03-18 06:56:53 +020043#ifdef HAVE_SYS_UIO_H
44#include <sys/uio.h>
45#endif
46
Thomas Wouters0e3f5912006-08-11 14:57:12 +000047#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000048#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000049#endif /* HAVE_SYS_TYPES_H */
50
51#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000052#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000053#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000054
Guido van Rossum36bc6801995-06-14 22:54:23 +000055#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000056#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000057#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000058
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000060#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000061#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000062
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#ifdef HAVE_FCNTL_H
64#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000065#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000066
Guido van Rossuma6535fd2001-10-18 19:44:10 +000067#ifdef HAVE_GRP_H
68#include <grp.h>
69#endif
70
Barry Warsaw5676bd12003-01-07 20:57:09 +000071#ifdef HAVE_SYSEXITS_H
72#include <sysexits.h>
73#endif /* HAVE_SYSEXITS_H */
74
Anthony Baxter8a560de2004-10-13 15:30:56 +000075#ifdef HAVE_SYS_LOADAVG_H
76#include <sys/loadavg.h>
77#endif
78
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000079#ifdef HAVE_LANGINFO_H
80#include <langinfo.h>
81#endif
82
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000083#ifdef HAVE_SYS_SENDFILE_H
84#include <sys/sendfile.h>
85#endif
86
Benjamin Peterson94b580d2011-08-02 17:30:04 -050087#ifdef HAVE_SCHED_H
88#include <sched.h>
89#endif
90
Benjamin Peterson2dbda072012-03-16 10:12:55 -050091#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050092#undef HAVE_SCHED_SETAFFINITY
93#endif
94
Benjamin Peterson9428d532011-09-14 11:45:52 -040095#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
96#define USE_XATTRS
97#endif
98
99#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400100#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400101#endif
102
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000103#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
104#ifdef HAVE_SYS_SOCKET_H
105#include <sys/socket.h>
106#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000107#endif
108
Victor Stinner8b905bd2011-10-25 13:34:04 +0200109#ifdef HAVE_DLFCN_H
110#include <dlfcn.h>
111#endif
112
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100113#if defined(MS_WINDOWS)
114# define TERMSIZE_USE_CONIO
115#elif defined(HAVE_SYS_IOCTL_H)
116# include <sys/ioctl.h>
117# if defined(HAVE_TERMIOS_H)
118# include <termios.h>
119# endif
120# if defined(TIOCGWINSZ)
121# define TERMSIZE_USE_IOCTL
122# endif
123#endif /* MS_WINDOWS */
124
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000126/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000127#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128#define HAVE_GETCWD 1
129#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000130#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000131#include <process.h>
132#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000133#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#define HAVE_EXECV 1
135#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#define HAVE_OPENDIR 1
137#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000138#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#define HAVE_WAIT 1
140#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000141#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000142#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000143#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000144#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000145#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_EXECV 1
147#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SYSTEM 1
149#define HAVE_CWAIT 1
150#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000151#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000152#else
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200153#if defined(__VMS)
154/* Everything needed is defined in vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156/* Unix functions that the configure script doesn't check for */
157#define HAVE_EXECV 1
158#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000160#define HAVE_FORK1 1
161#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_GETCWD 1
163#define HAVE_GETEGID 1
164#define HAVE_GETEUID 1
165#define HAVE_GETGID 1
166#define HAVE_GETPPID 1
167#define HAVE_GETUID 1
168#define HAVE_KILL 1
169#define HAVE_OPENDIR 1
170#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000173#define HAVE_TTYNAME 1
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200174#endif /* __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif /* _MSC_VER */
176#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000177#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000178
Victor Stinnera2f7c002012-02-08 03:36:25 +0100179
180
181
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000183
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000184#if defined(__sgi)&&_COMPILER_VERSION>=700
185/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
186 (default) */
187extern char *ctermid_r(char *);
188#endif
189
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000190#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000191#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000192extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000193#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000194#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000196#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000197extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000199#endif
200#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000201extern int chdir(char *);
202extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000203#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int chdir(const char *);
205extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000207#ifdef __BORLANDC__
208extern int chmod(const char *, int);
209#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000211#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000212/*#ifdef HAVE_FCHMOD
213extern int fchmod(int, mode_t);
214#endif*/
215/*#ifdef HAVE_LCHMOD
216extern int lchmod(const char *, mode_t);
217#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int chown(const char *, uid_t, gid_t);
219extern char *getcwd(char *, int);
220extern char *strerror(int);
221extern int link(const char *, const char *);
222extern int rename(const char *, const char *);
223extern int stat(const char *, struct stat *);
224extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000226extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000227#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000229extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000230#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000232
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000233#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#ifdef HAVE_UTIME_H
236#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000239#ifdef HAVE_SYS_UTIME_H
240#include <sys/utime.h>
241#define HAVE_UTIME_H /* pretend we do for the rest of this file */
242#endif /* HAVE_SYS_UTIME_H */
243
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#ifdef HAVE_SYS_TIMES_H
245#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247
248#ifdef HAVE_SYS_PARAM_H
249#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000250#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251
252#ifdef HAVE_SYS_UTSNAME_H
253#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000254#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000258#define NAMLEN(dirent) strlen((dirent)->d_name)
259#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000260#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000261#include <direct.h>
262#define NAMLEN(dirent) strlen((dirent)->d_name)
263#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000265#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000266#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000267#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#endif
270#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#endif
273#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000275#endif
276#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000278#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000279#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000281#endif
282#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000283#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000284#endif
285#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000287#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000288#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000289#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000290#endif
291#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000292#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000293#endif
294#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000295#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000296#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000297#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000298#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000300#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000301#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000302#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
303#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000304static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000305#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000306#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307
Tim Petersbc2e10e2002-03-03 23:17:02 +0000308#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000309#if defined(PATH_MAX) && PATH_MAX > 1024
310#define MAXPATHLEN PATH_MAX
311#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000312#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000313#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000314#endif /* MAXPATHLEN */
315
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000316#ifdef UNION_WAIT
317/* Emulate some macros on systems that have a union instead of macros */
318
319#ifndef WIFEXITED
320#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
321#endif
322
323#ifndef WEXITSTATUS
324#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
325#endif
326
327#ifndef WTERMSIG
328#define WTERMSIG(u_wait) ((u_wait).w_termsig)
329#endif
330
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000331#define WAIT_TYPE union wait
332#define WAIT_STATUS_INT(s) (s.w_status)
333
334#else /* !UNION_WAIT */
335#define WAIT_TYPE int
336#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000337#endif /* UNION_WAIT */
338
Greg Wardb48bc172000-03-01 21:51:56 +0000339/* Don't use the "_r" form if we don't need it (also, won't have a
340 prototype for it, at least on Solaris -- maybe others as well?). */
341#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
342#define USE_CTERMID_R
343#endif
344
Fred Drake699f3522000-06-29 21:12:41 +0000345/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000346#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000347#undef FSTAT
348#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000349#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000350# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700351# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000352# define FSTAT win32_fstat
353# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000354#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000355# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700356# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000357# define FSTAT fstat
358# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000359#endif
360
Tim Peters11b23062003-04-23 02:39:17 +0000361#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000362#include <sys/mkdev.h>
363#else
364#if defined(MAJOR_IN_SYSMACROS)
365#include <sys/sysmacros.h>
366#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000367#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
368#include <sys/mkdev.h>
369#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000370#endif
Fred Drake699f3522000-06-29 21:12:41 +0000371
Larry Hastings9cf065c2012-06-22 16:30:09 -0700372
373#ifdef MS_WINDOWS
374static int
375win32_warn_bytes_api()
376{
377 return PyErr_WarnEx(PyExc_DeprecationWarning,
378 "The Windows bytes API has been deprecated, "
379 "use Unicode filenames instead",
380 1);
381}
382#endif
383
384
385#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400386/*
387 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
388 * without the int cast, the value gets interpreted as uint (4291925331),
389 * which doesn't play nicely with all the initializer lines in this file that
390 * look like this:
391 * int dir_fd = DEFAULT_DIR_FD;
392 */
393#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700394#else
395#define DEFAULT_DIR_FD (-100)
396#endif
397
398static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200399_fd_converter(PyObject *o, int *p, const char *allowed)
400{
401 int overflow;
402 long long_value = PyLong_AsLongAndOverflow(o, &overflow);
403 if (PyFloat_Check(o) ||
404 (long_value == -1 && !overflow && PyErr_Occurred())) {
405 PyErr_Clear();
406 PyErr_Format(PyExc_TypeError,
407 "argument should be %s, not %.200s",
408 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700409 return 0;
410 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200411 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700412 PyErr_SetString(PyExc_OverflowError,
413 "signed integer is greater than maximum");
414 return 0;
415 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200416 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700417 PyErr_SetString(PyExc_OverflowError,
418 "signed integer is less than minimum");
419 return 0;
420 }
421 *p = (int)long_value;
422 return 1;
423}
424
425static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200426dir_fd_converter(PyObject *o, void *p)
427{
428 if (o == Py_None) {
429 *(int *)p = DEFAULT_DIR_FD;
430 return 1;
431 }
432 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700433}
434
435
436
437/*
438 * A PyArg_ParseTuple "converter" function
439 * that handles filesystem paths in the manner
440 * preferred by the os module.
441 *
442 * path_converter accepts (Unicode) strings and their
443 * subclasses, and bytes and their subclasses. What
444 * it does with the argument depends on the platform:
445 *
446 * * On Windows, if we get a (Unicode) string we
447 * extract the wchar_t * and return it; if we get
448 * bytes we extract the char * and return that.
449 *
450 * * On all other platforms, strings are encoded
451 * to bytes using PyUnicode_FSConverter, then we
452 * extract the char * from the bytes object and
453 * return that.
454 *
455 * path_converter also optionally accepts signed
456 * integers (representing open file descriptors) instead
457 * of path strings.
458 *
459 * Input fields:
460 * path.nullable
461 * If nonzero, the path is permitted to be None.
462 * path.allow_fd
463 * If nonzero, the path is permitted to be a file handle
464 * (a signed int) instead of a string.
465 * path.function_name
466 * If non-NULL, path_converter will use that as the name
467 * of the function in error messages.
468 * (If path.argument_name is NULL it omits the function name.)
469 * path.argument_name
470 * If non-NULL, path_converter will use that as the name
471 * of the parameter in error messages.
472 * (If path.argument_name is NULL it uses "path".)
473 *
474 * Output fields:
475 * path.wide
476 * Points to the path if it was expressed as Unicode
477 * and was not encoded. (Only used on Windows.)
478 * path.narrow
479 * Points to the path if it was expressed as bytes,
480 * or it was Unicode and was encoded to bytes.
481 * path.fd
482 * Contains a file descriptor if path.accept_fd was true
483 * and the caller provided a signed integer instead of any
484 * sort of string.
485 *
486 * WARNING: if your "path" parameter is optional, and is
487 * unspecified, path_converter will never get called.
488 * So if you set allow_fd, you *MUST* initialize path.fd = -1
489 * yourself!
490 * path.length
491 * The length of the path in characters, if specified as
492 * a string.
493 * path.object
494 * The original object passed in.
495 * path.cleanup
496 * For internal use only. May point to a temporary object.
497 * (Pay no attention to the man behind the curtain.)
498 *
499 * At most one of path.wide or path.narrow will be non-NULL.
500 * If path was None and path.nullable was set,
501 * or if path was an integer and path.allow_fd was set,
502 * both path.wide and path.narrow will be NULL
503 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200504 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700505 * path_converter takes care to not write to the path_t
506 * unless it's successful. However it must reset the
507 * "cleanup" field each time it's called.
508 *
509 * Use as follows:
510 * path_t path;
511 * memset(&path, 0, sizeof(path));
512 * PyArg_ParseTuple(args, "O&", path_converter, &path);
513 * // ... use values from path ...
514 * path_cleanup(&path);
515 *
516 * (Note that if PyArg_Parse fails you don't need to call
517 * path_cleanup(). However it is safe to do so.)
518 */
519typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100520 const char *function_name;
521 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700522 int nullable;
523 int allow_fd;
524 wchar_t *wide;
525 char *narrow;
526 int fd;
527 Py_ssize_t length;
528 PyObject *object;
529 PyObject *cleanup;
530} path_t;
531
532static void
533path_cleanup(path_t *path) {
534 if (path->cleanup) {
535 Py_DECREF(path->cleanup);
536 path->cleanup = NULL;
537 }
538}
539
540static int
541path_converter(PyObject *o, void *p) {
542 path_t *path = (path_t *)p;
543 PyObject *unicode, *bytes;
544 Py_ssize_t length;
545 char *narrow;
546
547#define FORMAT_EXCEPTION(exc, fmt) \
548 PyErr_Format(exc, "%s%s" fmt, \
549 path->function_name ? path->function_name : "", \
550 path->function_name ? ": " : "", \
551 path->argument_name ? path->argument_name : "path")
552
553 /* Py_CLEANUP_SUPPORTED support */
554 if (o == NULL) {
555 path_cleanup(path);
556 return 1;
557 }
558
559 /* ensure it's always safe to call path_cleanup() */
560 path->cleanup = NULL;
561
562 if (o == Py_None) {
563 if (!path->nullable) {
564 FORMAT_EXCEPTION(PyExc_TypeError,
565 "can't specify None for %s argument");
566 return 0;
567 }
568 path->wide = NULL;
569 path->narrow = NULL;
570 path->length = 0;
571 path->object = o;
572 path->fd = -1;
573 return 1;
574 }
575
576 unicode = PyUnicode_FromObject(o);
577 if (unicode) {
578#ifdef MS_WINDOWS
579 wchar_t *wide;
580 length = PyUnicode_GET_SIZE(unicode);
581 if (length > 32767) {
582 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
583 Py_DECREF(unicode);
584 return 0;
585 }
586
587 wide = PyUnicode_AsUnicode(unicode);
588 if (!wide) {
589 Py_DECREF(unicode);
590 return 0;
591 }
592
593 path->wide = wide;
594 path->narrow = NULL;
595 path->length = length;
596 path->object = o;
597 path->fd = -1;
598 path->cleanup = unicode;
599 return Py_CLEANUP_SUPPORTED;
600#else
601 int converted = PyUnicode_FSConverter(unicode, &bytes);
602 Py_DECREF(unicode);
603 if (!converted)
604 bytes = NULL;
605#endif
606 }
607 else {
608 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200609 if (PyObject_CheckBuffer(o))
610 bytes = PyBytes_FromObject(o);
611 else
612 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700613 if (!bytes) {
614 PyErr_Clear();
615 if (path->allow_fd) {
616 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200617 int result = _fd_converter(o, &fd,
618 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700619 if (result) {
620 path->wide = NULL;
621 path->narrow = NULL;
622 path->length = 0;
623 path->object = o;
624 path->fd = fd;
625 return result;
626 }
627 }
628 }
629 }
630
631 if (!bytes) {
632 if (!PyErr_Occurred())
633 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
634 return 0;
635 }
636
637#ifdef MS_WINDOWS
638 if (win32_warn_bytes_api()) {
639 Py_DECREF(bytes);
640 return 0;
641 }
642#endif
643
644 length = PyBytes_GET_SIZE(bytes);
645#ifdef MS_WINDOWS
646 if (length > MAX_PATH) {
647 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
648 Py_DECREF(bytes);
649 return 0;
650 }
651#endif
652
653 narrow = PyBytes_AS_STRING(bytes);
654 if (length != strlen(narrow)) {
655 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
656 Py_DECREF(bytes);
657 return 0;
658 }
659
660 path->wide = NULL;
661 path->narrow = narrow;
662 path->length = length;
663 path->object = o;
664 path->fd = -1;
665 path->cleanup = bytes;
666 return Py_CLEANUP_SUPPORTED;
667}
668
669static void
670argument_unavailable_error(char *function_name, char *argument_name) {
671 PyErr_Format(PyExc_NotImplementedError,
672 "%s%s%s unavailable on this platform",
673 (function_name != NULL) ? function_name : "",
674 (function_name != NULL) ? ": ": "",
675 argument_name);
676}
677
678static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200679dir_fd_unavailable(PyObject *o, void *p)
680{
681 int dir_fd;
682 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700683 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200684 if (dir_fd != DEFAULT_DIR_FD) {
685 argument_unavailable_error(NULL, "dir_fd");
686 return 0;
687 }
688 *(int *)p = dir_fd;
689 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700690}
691
692static int
693fd_specified(char *function_name, int fd) {
694 if (fd == -1)
695 return 0;
696
697 argument_unavailable_error(function_name, "fd");
698 return 1;
699}
700
701static int
702follow_symlinks_specified(char *function_name, int follow_symlinks) {
703 if (follow_symlinks)
704 return 0;
705
706 argument_unavailable_error(function_name, "follow_symlinks");
707 return 1;
708}
709
710static int
711path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
712 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
713 PyErr_Format(PyExc_ValueError,
714 "%s: can't specify dir_fd without matching path",
715 function_name);
716 return 1;
717 }
718 return 0;
719}
720
721static int
722dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
723 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
724 PyErr_Format(PyExc_ValueError,
725 "%s: can't specify both dir_fd and fd",
726 function_name);
727 return 1;
728 }
729 return 0;
730}
731
732static int
733fd_and_follow_symlinks_invalid(char *function_name, int fd,
734 int follow_symlinks) {
735 if ((fd > 0) && (!follow_symlinks)) {
736 PyErr_Format(PyExc_ValueError,
737 "%s: cannot use fd and follow_symlinks together",
738 function_name);
739 return 1;
740 }
741 return 0;
742}
743
744static int
745dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
746 int follow_symlinks) {
747 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
748 PyErr_Format(PyExc_ValueError,
749 "%s: cannot use dir_fd and follow_symlinks together",
750 function_name);
751 return 1;
752 }
753 return 0;
754}
755
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200756/* A helper used by a number of POSIX-only functions */
757#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000758static int
759_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000760{
761#if !defined(HAVE_LARGEFILE_SUPPORT)
762 *((off_t*)addr) = PyLong_AsLong(arg);
763#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000764 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000765#endif
766 if (PyErr_Occurred())
767 return 0;
768 return 1;
769}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200770#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000771
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000772#if defined _MSC_VER && _MSC_VER >= 1400
773/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200774 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000775 * Normally, an invalid fd is likely to be a C program error and therefore
776 * an assertion can be useful, but it does contradict the POSIX standard
777 * which for write(2) states:
778 * "Otherwise, -1 shall be returned and errno set to indicate the error."
779 * "[EBADF] The fildes argument is not a valid file descriptor open for
780 * writing."
781 * Furthermore, python allows the user to enter any old integer
782 * as a fd and should merely raise a python exception on error.
783 * The Microsoft CRT doesn't provide an official way to check for the
784 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000785 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000786 * internal structures involved.
787 * The structures below must be updated for each version of visual studio
788 * according to the file internal.h in the CRT source, until MS comes
789 * up with a less hacky way to do this.
790 * (all of this is to avoid globally modifying the CRT behaviour using
791 * _set_invalid_parameter_handler() and _CrtSetReportMode())
792 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000793/* The actual size of the structure is determined at runtime.
794 * Only the first items must be present.
795 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000796typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000797 intptr_t osfhnd;
798 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000799} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000800
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000801extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000802#define IOINFO_L2E 5
803#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
804#define IOINFO_ARRAYS 64
805#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
806#define FOPEN 0x01
807#define _NO_CONSOLE_FILENO (intptr_t)-2
808
809/* This function emulates what the windows CRT does to validate file handles */
810int
811_PyVerify_fd(int fd)
812{
Victor Stinner8c62be82010-05-06 00:08:46 +0000813 const int i1 = fd >> IOINFO_L2E;
814 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000815
Antoine Pitrou22e41552010-08-15 18:07:50 +0000816 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000817
Victor Stinner8c62be82010-05-06 00:08:46 +0000818 /* Determine the actual size of the ioinfo structure,
819 * as used by the CRT loaded in memory
820 */
821 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
822 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
823 }
824 if (sizeof_ioinfo == 0) {
825 /* This should not happen... */
826 goto fail;
827 }
828
829 /* See that it isn't a special CLEAR fileno */
830 if (fd != _NO_CONSOLE_FILENO) {
831 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
832 * we check pointer validity and other info
833 */
834 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
835 /* finally, check that the file is open */
836 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
837 if (info->osfile & FOPEN) {
838 return 1;
839 }
840 }
841 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000842 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000843 errno = EBADF;
844 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000845}
846
847/* the special case of checking dup2. The target fd must be in a sensible range */
848static int
849_PyVerify_fd_dup2(int fd1, int fd2)
850{
Victor Stinner8c62be82010-05-06 00:08:46 +0000851 if (!_PyVerify_fd(fd1))
852 return 0;
853 if (fd2 == _NO_CONSOLE_FILENO)
854 return 0;
855 if ((unsigned)fd2 < _NHANDLE_)
856 return 1;
857 else
858 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000859}
860#else
861/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
862#define _PyVerify_fd_dup2(A, B) (1)
863#endif
864
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000865#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000866/* The following structure was copied from
867 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
868 include doesn't seem to be present in the Windows SDK (at least as included
869 with Visual Studio Express). */
870typedef struct _REPARSE_DATA_BUFFER {
871 ULONG ReparseTag;
872 USHORT ReparseDataLength;
873 USHORT Reserved;
874 union {
875 struct {
876 USHORT SubstituteNameOffset;
877 USHORT SubstituteNameLength;
878 USHORT PrintNameOffset;
879 USHORT PrintNameLength;
880 ULONG Flags;
881 WCHAR PathBuffer[1];
882 } SymbolicLinkReparseBuffer;
883
884 struct {
885 USHORT SubstituteNameOffset;
886 USHORT SubstituteNameLength;
887 USHORT PrintNameOffset;
888 USHORT PrintNameLength;
889 WCHAR PathBuffer[1];
890 } MountPointReparseBuffer;
891
892 struct {
893 UCHAR DataBuffer[1];
894 } GenericReparseBuffer;
895 };
896} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
897
898#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
899 GenericReparseBuffer)
900#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
901
902static int
Brian Curtind25aef52011-06-13 15:16:04 -0500903win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000904{
905 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
906 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
907 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000908
909 if (0 == DeviceIoControl(
910 reparse_point_handle,
911 FSCTL_GET_REPARSE_POINT,
912 NULL, 0, /* in buffer */
913 target_buffer, sizeof(target_buffer),
914 &n_bytes_returned,
915 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500916 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000917
918 if (reparse_tag)
919 *reparse_tag = rdb->ReparseTag;
920
Brian Curtind25aef52011-06-13 15:16:04 -0500921 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000922}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100923
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000924#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000925
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000926/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +0100927#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +0000928/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +0100929** environ directly, we must obtain it with _NSGetEnviron(). See also
930** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +0000931*/
932#include <crt_externs.h>
933static char **environ;
934#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000935extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000936#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000937
Barry Warsaw53699e91996-12-10 23:23:01 +0000938static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000939convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000940{
Victor Stinner8c62be82010-05-06 00:08:46 +0000941 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000942#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000943 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000944#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000945 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000946#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000947
Victor Stinner8c62be82010-05-06 00:08:46 +0000948 d = PyDict_New();
949 if (d == NULL)
950 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +0100951#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +0000952 if (environ == NULL)
953 environ = *_NSGetEnviron();
954#endif
955#ifdef MS_WINDOWS
956 /* _wenviron must be initialized in this way if the program is started
957 through main() instead of wmain(). */
958 _wgetenv(L"");
959 if (_wenviron == NULL)
960 return d;
961 /* This part ignores errors */
962 for (e = _wenviron; *e != NULL; e++) {
963 PyObject *k;
964 PyObject *v;
965 wchar_t *p = wcschr(*e, L'=');
966 if (p == NULL)
967 continue;
968 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
969 if (k == NULL) {
970 PyErr_Clear();
971 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000972 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000973 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
974 if (v == NULL) {
975 PyErr_Clear();
976 Py_DECREF(k);
977 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000978 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000979 if (PyDict_GetItem(d, k) == NULL) {
980 if (PyDict_SetItem(d, k, v) != 0)
981 PyErr_Clear();
982 }
983 Py_DECREF(k);
984 Py_DECREF(v);
985 }
986#else
987 if (environ == NULL)
988 return d;
989 /* This part ignores errors */
990 for (e = environ; *e != NULL; e++) {
991 PyObject *k;
992 PyObject *v;
993 char *p = strchr(*e, '=');
994 if (p == NULL)
995 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000996 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000997 if (k == NULL) {
998 PyErr_Clear();
999 continue;
1000 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001001 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001002 if (v == NULL) {
1003 PyErr_Clear();
1004 Py_DECREF(k);
1005 continue;
1006 }
1007 if (PyDict_GetItem(d, k) == NULL) {
1008 if (PyDict_SetItem(d, k, v) != 0)
1009 PyErr_Clear();
1010 }
1011 Py_DECREF(k);
1012 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001013 }
1014#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001015 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001016}
1017
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001018/* Set a POSIX-specific error from errno, and return NULL */
1019
Barry Warsawd58d7641998-07-23 16:14:40 +00001020static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001021posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001022{
Victor Stinner8c62be82010-05-06 00:08:46 +00001023 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001024}
Mark Hammondef8b6542001-05-13 08:04:26 +00001025
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001026#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001027static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001028win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001029{
Victor Stinner8c62be82010-05-06 00:08:46 +00001030 /* XXX We should pass the function name along in the future.
1031 (winreg.c also wants to pass the function name.)
1032 This would however require an additional param to the
1033 Windows error object, which is non-trivial.
1034 */
1035 errno = GetLastError();
1036 if (filename)
1037 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1038 else
1039 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001040}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001041
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001042static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001043win32_error_object(char* function, PyObject* filename)
1044{
1045 /* XXX - see win32_error for comments on 'function' */
1046 errno = GetLastError();
1047 if (filename)
1048 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001049 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001050 errno,
1051 filename);
1052 else
1053 return PyErr_SetFromWindowsErr(errno);
1054}
1055
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001056#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001057
Larry Hastings9cf065c2012-06-22 16:30:09 -07001058static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001059path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001060{
1061#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001062 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1063 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001064#else
Victor Stinner292c8352012-10-30 02:17:38 +01001065 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001066#endif
1067}
1068
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001069/* POSIX generic methods */
1070
Barry Warsaw53699e91996-12-10 23:23:01 +00001071static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001072posix_fildes(PyObject *fdobj, int (*func)(int))
1073{
Victor Stinner8c62be82010-05-06 00:08:46 +00001074 int fd;
1075 int res;
1076 fd = PyObject_AsFileDescriptor(fdobj);
1077 if (fd < 0)
1078 return NULL;
1079 if (!_PyVerify_fd(fd))
1080 return posix_error();
1081 Py_BEGIN_ALLOW_THREADS
1082 res = (*func)(fd);
1083 Py_END_ALLOW_THREADS
1084 if (res < 0)
1085 return posix_error();
1086 Py_INCREF(Py_None);
1087 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001088}
Guido van Rossum21142a01999-01-08 21:05:37 +00001089
1090static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001091posix_1str(const char *func_name, PyObject *args, char *format,
1092 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001093{
Victor Stinner292c8352012-10-30 02:17:38 +01001094 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001095 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001096 memset(&path, 0, sizeof(path));
1097 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001098 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001099 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001100 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001101 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001102 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001103 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001104 if (res < 0) {
1105 path_error(&path);
1106 path_cleanup(&path);
1107 return NULL;
1108 }
1109 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001110 Py_INCREF(Py_None);
1111 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001112}
1113
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001114
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001115#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001116/* This is a reimplementation of the C library's chdir function,
1117 but one that produces Win32 errors instead of DOS error codes.
1118 chdir is essentially a wrapper around SetCurrentDirectory; however,
1119 it also needs to set "magic" environment variables indicating
1120 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001121static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001122win32_chdir(LPCSTR path)
1123{
Victor Stinner8c62be82010-05-06 00:08:46 +00001124 char new_path[MAX_PATH+1];
1125 int result;
1126 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001127
Victor Stinner8c62be82010-05-06 00:08:46 +00001128 if(!SetCurrentDirectoryA(path))
1129 return FALSE;
1130 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1131 if (!result)
1132 return FALSE;
1133 /* In the ANSI API, there should not be any paths longer
1134 than MAX_PATH. */
1135 assert(result <= MAX_PATH+1);
1136 if (strncmp(new_path, "\\\\", 2) == 0 ||
1137 strncmp(new_path, "//", 2) == 0)
1138 /* UNC path, nothing to do. */
1139 return TRUE;
1140 env[1] = new_path[0];
1141 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001142}
1143
1144/* The Unicode version differs from the ANSI version
1145 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001146static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001147win32_wchdir(LPCWSTR path)
1148{
Victor Stinner8c62be82010-05-06 00:08:46 +00001149 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1150 int result;
1151 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001152
Victor Stinner8c62be82010-05-06 00:08:46 +00001153 if(!SetCurrentDirectoryW(path))
1154 return FALSE;
1155 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1156 if (!result)
1157 return FALSE;
1158 if (result > MAX_PATH+1) {
1159 new_path = malloc(result * sizeof(wchar_t));
1160 if (!new_path) {
1161 SetLastError(ERROR_OUTOFMEMORY);
1162 return FALSE;
1163 }
1164 result = GetCurrentDirectoryW(result, new_path);
1165 if (!result) {
1166 free(new_path);
1167 return FALSE;
1168 }
1169 }
1170 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1171 wcsncmp(new_path, L"//", 2) == 0)
1172 /* UNC path, nothing to do. */
1173 return TRUE;
1174 env[1] = new_path[0];
1175 result = SetEnvironmentVariableW(env, new_path);
1176 if (new_path != _new_path)
1177 free(new_path);
1178 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001179}
1180#endif
1181
Martin v. Löwis14694662006-02-03 12:54:16 +00001182#ifdef MS_WINDOWS
1183/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1184 - time stamps are restricted to second resolution
1185 - file modification times suffer from forth-and-back conversions between
1186 UTC and local time
1187 Therefore, we implement our own stat, based on the Win32 API directly.
1188*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001189#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001190
1191struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001192 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001193 __int64 st_ino;
1194 unsigned short st_mode;
1195 int st_nlink;
1196 int st_uid;
1197 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001198 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001199 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001200 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001201 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001202 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001203 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001204 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001205 int st_ctime_nsec;
1206};
1207
1208static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1209
1210static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001211FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001212{
Victor Stinner8c62be82010-05-06 00:08:46 +00001213 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1214 /* Cannot simply cast and dereference in_ptr,
1215 since it might not be aligned properly */
1216 __int64 in;
1217 memcpy(&in, in_ptr, sizeof(in));
1218 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001219 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001220}
1221
Thomas Wouters477c8d52006-05-27 19:21:47 +00001222static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001223time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001224{
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 /* XXX endianness */
1226 __int64 out;
1227 out = time_in + secs_between_epochs;
1228 out = out * 10000000 + nsec_in / 100;
1229 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001230}
1231
Martin v. Löwis14694662006-02-03 12:54:16 +00001232/* Below, we *know* that ugo+r is 0444 */
1233#if _S_IREAD != 0400
1234#error Unsupported C library
1235#endif
1236static int
1237attributes_to_mode(DWORD attr)
1238{
Victor Stinner8c62be82010-05-06 00:08:46 +00001239 int m = 0;
1240 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1241 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1242 else
1243 m |= _S_IFREG;
1244 if (attr & FILE_ATTRIBUTE_READONLY)
1245 m |= 0444;
1246 else
1247 m |= 0666;
1248 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001249}
1250
1251static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001252attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001253{
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 memset(result, 0, sizeof(*result));
1255 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1256 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001257 result->st_dev = info->dwVolumeSerialNumber;
1258 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001259 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1260 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1261 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001262 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001263 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001264 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1265 /* first clear the S_IFMT bits */
1266 result->st_mode ^= (result->st_mode & 0170000);
1267 /* now set the bits that make this a symlink */
1268 result->st_mode |= 0120000;
1269 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001270
Victor Stinner8c62be82010-05-06 00:08:46 +00001271 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001272}
1273
Guido van Rossumd8faa362007-04-27 19:54:29 +00001274static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001275attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001276{
Victor Stinner8c62be82010-05-06 00:08:46 +00001277 HANDLE hFindFile;
1278 WIN32_FIND_DATAA FileData;
1279 hFindFile = FindFirstFileA(pszFile, &FileData);
1280 if (hFindFile == INVALID_HANDLE_VALUE)
1281 return FALSE;
1282 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001283 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001284 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001285 info->dwFileAttributes = FileData.dwFileAttributes;
1286 info->ftCreationTime = FileData.ftCreationTime;
1287 info->ftLastAccessTime = FileData.ftLastAccessTime;
1288 info->ftLastWriteTime = FileData.ftLastWriteTime;
1289 info->nFileSizeHigh = FileData.nFileSizeHigh;
1290 info->nFileSizeLow = FileData.nFileSizeLow;
1291/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001292 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1293 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001294 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001295}
1296
1297static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001298attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001299{
Victor Stinner8c62be82010-05-06 00:08:46 +00001300 HANDLE hFindFile;
1301 WIN32_FIND_DATAW FileData;
1302 hFindFile = FindFirstFileW(pszFile, &FileData);
1303 if (hFindFile == INVALID_HANDLE_VALUE)
1304 return FALSE;
1305 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001306 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001307 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001308 info->dwFileAttributes = FileData.dwFileAttributes;
1309 info->ftCreationTime = FileData.ftCreationTime;
1310 info->ftLastAccessTime = FileData.ftLastAccessTime;
1311 info->ftLastWriteTime = FileData.ftLastWriteTime;
1312 info->nFileSizeHigh = FileData.nFileSizeHigh;
1313 info->nFileSizeLow = FileData.nFileSizeLow;
1314/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001315 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1316 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001317 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001318}
1319
Brian Curtind25aef52011-06-13 15:16:04 -05001320/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001321static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001322static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1323 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001324static int
Brian Curtind25aef52011-06-13 15:16:04 -05001325check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001326{
Brian Curtind25aef52011-06-13 15:16:04 -05001327 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001328 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1329 DWORD);
1330
Brian Curtind25aef52011-06-13 15:16:04 -05001331 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001332 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001333 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001334 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001335 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1336 "GetFinalPathNameByHandleA");
1337 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1338 "GetFinalPathNameByHandleW");
1339 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1340 Py_GetFinalPathNameByHandleW;
1341 }
1342 return has_GetFinalPathNameByHandle;
1343}
1344
1345static BOOL
1346get_target_path(HANDLE hdl, wchar_t **target_path)
1347{
1348 int buf_size, result_length;
1349 wchar_t *buf;
1350
1351 /* We have a good handle to the target, use it to determine
1352 the target path name (then we'll call lstat on it). */
1353 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1354 VOLUME_NAME_DOS);
1355 if(!buf_size)
1356 return FALSE;
1357
1358 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001359 if (!buf) {
1360 SetLastError(ERROR_OUTOFMEMORY);
1361 return FALSE;
1362 }
1363
Brian Curtind25aef52011-06-13 15:16:04 -05001364 result_length = Py_GetFinalPathNameByHandleW(hdl,
1365 buf, buf_size, VOLUME_NAME_DOS);
1366
1367 if(!result_length) {
1368 free(buf);
1369 return FALSE;
1370 }
1371
1372 if(!CloseHandle(hdl)) {
1373 free(buf);
1374 return FALSE;
1375 }
1376
1377 buf[result_length] = 0;
1378
1379 *target_path = buf;
1380 return TRUE;
1381}
1382
1383static int
1384win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1385 BOOL traverse);
1386static int
1387win32_xstat_impl(const char *path, struct win32_stat *result,
1388 BOOL traverse)
1389{
Victor Stinner26de69d2011-06-17 15:15:38 +02001390 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001391 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001392 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001393 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001394 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001395 const char *dot;
1396
Brian Curtind25aef52011-06-13 15:16:04 -05001397 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001398 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1399 traverse reparse point. */
1400 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001401 }
1402
Brian Curtinf5e76d02010-11-24 13:14:05 +00001403 hFile = CreateFileA(
1404 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001405 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001406 0, /* share mode */
1407 NULL, /* security attributes */
1408 OPEN_EXISTING,
1409 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001410 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1411 Because of this, calls like GetFinalPathNameByHandle will return
1412 the symlink path agin and not the actual final path. */
1413 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1414 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001415 NULL);
1416
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001417 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001418 /* Either the target doesn't exist, or we don't have access to
1419 get a handle to it. If the former, we need to return an error.
1420 If the latter, we can use attributes_from_dir. */
1421 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001422 return -1;
1423 /* Could not get attributes on open file. Fall back to
1424 reading the directory. */
1425 if (!attributes_from_dir(path, &info, &reparse_tag))
1426 /* Very strange. This should not fail now */
1427 return -1;
1428 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1429 if (traverse) {
1430 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001431 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001432 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001433 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001434 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001435 } else {
1436 if (!GetFileInformationByHandle(hFile, &info)) {
1437 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001438 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001439 }
1440 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001441 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1442 return -1;
1443
1444 /* Close the outer open file handle now that we're about to
1445 reopen it with different flags. */
1446 if (!CloseHandle(hFile))
1447 return -1;
1448
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001449 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001450 /* In order to call GetFinalPathNameByHandle we need to open
1451 the file without the reparse handling flag set. */
1452 hFile2 = CreateFileA(
1453 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1454 NULL, OPEN_EXISTING,
1455 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1456 NULL);
1457 if (hFile2 == INVALID_HANDLE_VALUE)
1458 return -1;
1459
1460 if (!get_target_path(hFile2, &target_path))
1461 return -1;
1462
1463 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001464 free(target_path);
1465 return code;
1466 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001467 } else
1468 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001469 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001470 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001471
1472 /* Set S_IEXEC if it is an .exe, .bat, ... */
1473 dot = strrchr(path, '.');
1474 if (dot) {
1475 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1476 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1477 result->st_mode |= 0111;
1478 }
1479 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001480}
1481
1482static int
Brian Curtind25aef52011-06-13 15:16:04 -05001483win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1484 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001485{
1486 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001487 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001488 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001489 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001490 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001491 const wchar_t *dot;
1492
Brian Curtind25aef52011-06-13 15:16:04 -05001493 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001494 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1495 traverse reparse point. */
1496 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001497 }
1498
Brian Curtinf5e76d02010-11-24 13:14:05 +00001499 hFile = CreateFileW(
1500 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001501 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001502 0, /* share mode */
1503 NULL, /* security attributes */
1504 OPEN_EXISTING,
1505 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001506 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1507 Because of this, calls like GetFinalPathNameByHandle will return
1508 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001509 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001510 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001511 NULL);
1512
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001513 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001514 /* Either the target doesn't exist, or we don't have access to
1515 get a handle to it. If the former, we need to return an error.
1516 If the latter, we can use attributes_from_dir. */
1517 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001518 return -1;
1519 /* Could not get attributes on open file. Fall back to
1520 reading the directory. */
1521 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1522 /* Very strange. This should not fail now */
1523 return -1;
1524 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1525 if (traverse) {
1526 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001527 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001528 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001529 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001530 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001531 } else {
1532 if (!GetFileInformationByHandle(hFile, &info)) {
1533 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001534 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001535 }
1536 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001537 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1538 return -1;
1539
1540 /* Close the outer open file handle now that we're about to
1541 reopen it with different flags. */
1542 if (!CloseHandle(hFile))
1543 return -1;
1544
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001545 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001546 /* In order to call GetFinalPathNameByHandle we need to open
1547 the file without the reparse handling flag set. */
1548 hFile2 = CreateFileW(
1549 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1550 NULL, OPEN_EXISTING,
1551 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1552 NULL);
1553 if (hFile2 == INVALID_HANDLE_VALUE)
1554 return -1;
1555
1556 if (!get_target_path(hFile2, &target_path))
1557 return -1;
1558
1559 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001560 free(target_path);
1561 return code;
1562 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001563 } else
1564 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001565 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001566 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001567
1568 /* Set S_IEXEC if it is an .exe, .bat, ... */
1569 dot = wcsrchr(path, '.');
1570 if (dot) {
1571 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1572 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1573 result->st_mode |= 0111;
1574 }
1575 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001576}
1577
1578static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001579win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001580{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001581 /* Protocol violation: we explicitly clear errno, instead of
1582 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001583 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001584 errno = 0;
1585 return code;
1586}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001587
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001588static int
1589win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1590{
1591 /* Protocol violation: we explicitly clear errno, instead of
1592 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001593 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001594 errno = 0;
1595 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001596}
Brian Curtind25aef52011-06-13 15:16:04 -05001597/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001598
1599 In Posix, stat automatically traverses symlinks and returns the stat
1600 structure for the target. In Windows, the equivalent GetFileAttributes by
1601 default does not traverse symlinks and instead returns attributes for
1602 the symlink.
1603
1604 Therefore, win32_lstat will get the attributes traditionally, and
1605 win32_stat will first explicitly resolve the symlink target and then will
1606 call win32_lstat on that result.
1607
Ezio Melotti4969f702011-03-15 05:59:46 +02001608 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001609
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001610static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001611win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001612{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001613 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001614}
1615
Victor Stinner8c62be82010-05-06 00:08:46 +00001616static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001617win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001618{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001619 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001620}
1621
1622static int
1623win32_stat(const char* path, struct win32_stat *result)
1624{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001625 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001626}
1627
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001628static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001629win32_stat_w(const wchar_t* path, struct win32_stat *result)
1630{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001631 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001632}
1633
1634static int
1635win32_fstat(int file_number, struct win32_stat *result)
1636{
Victor Stinner8c62be82010-05-06 00:08:46 +00001637 BY_HANDLE_FILE_INFORMATION info;
1638 HANDLE h;
1639 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001640
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001641 if (!_PyVerify_fd(file_number))
1642 h = INVALID_HANDLE_VALUE;
1643 else
1644 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001645
Victor Stinner8c62be82010-05-06 00:08:46 +00001646 /* Protocol violation: we explicitly clear errno, instead of
1647 setting it to a POSIX error. Callers should use GetLastError. */
1648 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001649
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 if (h == INVALID_HANDLE_VALUE) {
1651 /* This is really a C library error (invalid file handle).
1652 We set the Win32 error to the closes one matching. */
1653 SetLastError(ERROR_INVALID_HANDLE);
1654 return -1;
1655 }
1656 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001657
Victor Stinner8c62be82010-05-06 00:08:46 +00001658 type = GetFileType(h);
1659 if (type == FILE_TYPE_UNKNOWN) {
1660 DWORD error = GetLastError();
1661 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001663 }
1664 /* else: valid but unknown file */
1665 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001666
Victor Stinner8c62be82010-05-06 00:08:46 +00001667 if (type != FILE_TYPE_DISK) {
1668 if (type == FILE_TYPE_CHAR)
1669 result->st_mode = _S_IFCHR;
1670 else if (type == FILE_TYPE_PIPE)
1671 result->st_mode = _S_IFIFO;
1672 return 0;
1673 }
1674
1675 if (!GetFileInformationByHandle(h, &info)) {
1676 return -1;
1677 }
1678
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001680 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001681 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1682 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001683}
1684
1685#endif /* MS_WINDOWS */
1686
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001687PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001688"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001689This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001690 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001691or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1692\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001693Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1694or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001695\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001696See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001697
1698static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001699 {"st_mode", "protection bits"},
1700 {"st_ino", "inode"},
1701 {"st_dev", "device"},
1702 {"st_nlink", "number of hard links"},
1703 {"st_uid", "user ID of owner"},
1704 {"st_gid", "group ID of owner"},
1705 {"st_size", "total size, in bytes"},
1706 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1707 {NULL, "integer time of last access"},
1708 {NULL, "integer time of last modification"},
1709 {NULL, "integer time of last change"},
1710 {"st_atime", "time of last access"},
1711 {"st_mtime", "time of last modification"},
1712 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001713 {"st_atime_ns", "time of last access in nanoseconds"},
1714 {"st_mtime_ns", "time of last modification in nanoseconds"},
1715 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001716#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001717 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001718#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001719#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001720 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001721#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001722#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001723 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001724#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001725#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001726 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001727#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001728#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001729 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001730#endif
1731#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001732 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001733#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001734 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001735};
1736
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001737#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001738#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001739#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001740#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001741#endif
1742
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001743#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001744#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1745#else
1746#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1747#endif
1748
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001749#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001750#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1751#else
1752#define ST_RDEV_IDX ST_BLOCKS_IDX
1753#endif
1754
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001755#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1756#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1757#else
1758#define ST_FLAGS_IDX ST_RDEV_IDX
1759#endif
1760
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001761#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001762#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001763#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001764#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001765#endif
1766
1767#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1768#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1769#else
1770#define ST_BIRTHTIME_IDX ST_GEN_IDX
1771#endif
1772
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001773static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001774 "stat_result", /* name */
1775 stat_result__doc__, /* doc */
1776 stat_result_fields,
1777 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001778};
1779
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001780PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001781"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1782This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001783 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001784or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001785\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001786See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001787
1788static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001789 {"f_bsize", },
1790 {"f_frsize", },
1791 {"f_blocks", },
1792 {"f_bfree", },
1793 {"f_bavail", },
1794 {"f_files", },
1795 {"f_ffree", },
1796 {"f_favail", },
1797 {"f_flag", },
1798 {"f_namemax",},
1799 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001800};
1801
1802static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001803 "statvfs_result", /* name */
1804 statvfs_result__doc__, /* doc */
1805 statvfs_result_fields,
1806 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001807};
1808
Ross Lagerwall7807c352011-03-17 20:20:30 +02001809#if defined(HAVE_WAITID) && !defined(__APPLE__)
1810PyDoc_STRVAR(waitid_result__doc__,
1811"waitid_result: Result from waitid.\n\n\
1812This object may be accessed either as a tuple of\n\
1813 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1814or via the attributes si_pid, si_uid, and so on.\n\
1815\n\
1816See os.waitid for more information.");
1817
1818static PyStructSequence_Field waitid_result_fields[] = {
1819 {"si_pid", },
1820 {"si_uid", },
1821 {"si_signo", },
1822 {"si_status", },
1823 {"si_code", },
1824 {0}
1825};
1826
1827static PyStructSequence_Desc waitid_result_desc = {
1828 "waitid_result", /* name */
1829 waitid_result__doc__, /* doc */
1830 waitid_result_fields,
1831 5
1832};
1833static PyTypeObject WaitidResultType;
1834#endif
1835
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001836static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001837static PyTypeObject StatResultType;
1838static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001839#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001840static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001841#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001842static newfunc structseq_new;
1843
1844static PyObject *
1845statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1846{
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 PyStructSequence *result;
1848 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001849
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 result = (PyStructSequence*)structseq_new(type, args, kwds);
1851 if (!result)
1852 return NULL;
1853 /* If we have been initialized from a tuple,
1854 st_?time might be set to None. Initialize it
1855 from the int slots. */
1856 for (i = 7; i <= 9; i++) {
1857 if (result->ob_item[i+3] == Py_None) {
1858 Py_DECREF(Py_None);
1859 Py_INCREF(result->ob_item[i]);
1860 result->ob_item[i+3] = result->ob_item[i];
1861 }
1862 }
1863 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001864}
1865
1866
1867
1868/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001869static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001870
1871PyDoc_STRVAR(stat_float_times__doc__,
1872"stat_float_times([newval]) -> oldval\n\n\
1873Determine whether os.[lf]stat represents time stamps as float objects.\n\
1874If newval is True, future calls to stat() return floats, if it is False,\n\
1875future calls return ints. \n\
1876If newval is omitted, return the current setting.\n");
1877
1878static PyObject*
1879stat_float_times(PyObject* self, PyObject *args)
1880{
Victor Stinner8c62be82010-05-06 00:08:46 +00001881 int newval = -1;
1882 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1883 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001884 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1885 "stat_float_times() is deprecated",
1886 1))
1887 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001888 if (newval == -1)
1889 /* Return old value */
1890 return PyBool_FromLong(_stat_float_times);
1891 _stat_float_times = newval;
1892 Py_INCREF(Py_None);
1893 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001894}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001895
Larry Hastings6fe20b32012-04-19 15:07:49 -07001896static PyObject *billion = NULL;
1897
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001898static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001899fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001900{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001901 PyObject *s = _PyLong_FromTime_t(sec);
1902 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1903 PyObject *s_in_ns = NULL;
1904 PyObject *ns_total = NULL;
1905 PyObject *float_s = NULL;
1906
1907 if (!(s && ns_fractional))
1908 goto exit;
1909
1910 s_in_ns = PyNumber_Multiply(s, billion);
1911 if (!s_in_ns)
1912 goto exit;
1913
1914 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1915 if (!ns_total)
1916 goto exit;
1917
Victor Stinner4195b5c2012-02-08 23:03:19 +01001918 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001919 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1920 if (!float_s)
1921 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001922 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001923 else {
1924 float_s = s;
1925 Py_INCREF(float_s);
1926 }
1927
1928 PyStructSequence_SET_ITEM(v, index, s);
1929 PyStructSequence_SET_ITEM(v, index+3, float_s);
1930 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1931 s = NULL;
1932 float_s = NULL;
1933 ns_total = NULL;
1934exit:
1935 Py_XDECREF(s);
1936 Py_XDECREF(ns_fractional);
1937 Py_XDECREF(s_in_ns);
1938 Py_XDECREF(ns_total);
1939 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001940}
1941
Tim Peters5aa91602002-01-30 05:46:57 +00001942/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001943 (used by posix_stat() and posix_fstat()) */
1944static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001945_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001946{
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 unsigned long ansec, mnsec, cnsec;
1948 PyObject *v = PyStructSequence_New(&StatResultType);
1949 if (v == NULL)
1950 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001951
Victor Stinner8c62be82010-05-06 00:08:46 +00001952 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001953#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001954 PyStructSequence_SET_ITEM(v, 1,
1955 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001956#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001957 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001958#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001959#ifdef MS_WINDOWS
1960 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
1961#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 PyStructSequence_SET_ITEM(v, 2,
1963 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001964#else
Brian Curtin9cc43212013-01-01 12:31:06 -06001965 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001966#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001967 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1968 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1969 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001970#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 PyStructSequence_SET_ITEM(v, 6,
1972 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001973#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001975#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001976
Martin v. Löwis14694662006-02-03 12:54:16 +00001977#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 ansec = st->st_atim.tv_nsec;
1979 mnsec = st->st_mtim.tv_nsec;
1980 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001981#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 ansec = st->st_atimespec.tv_nsec;
1983 mnsec = st->st_mtimespec.tv_nsec;
1984 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001985#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 ansec = st->st_atime_nsec;
1987 mnsec = st->st_mtime_nsec;
1988 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001989#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001991#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001992 fill_time(v, 7, st->st_atime, ansec);
1993 fill_time(v, 8, st->st_mtime, mnsec);
1994 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001995
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001996#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1998 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001999#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002000#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2002 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002003#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002004#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2006 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002007#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002008#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002009 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2010 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002011#endif
2012#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002014 PyObject *val;
2015 unsigned long bsec,bnsec;
2016 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002017#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002018 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002019#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002020 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002021#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002022 if (_stat_float_times) {
2023 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2024 } else {
2025 val = PyLong_FromLong((long)bsec);
2026 }
2027 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2028 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002030#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002031#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2033 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002034#endif
Fred Drake699f3522000-06-29 21:12:41 +00002035
Victor Stinner8c62be82010-05-06 00:08:46 +00002036 if (PyErr_Occurred()) {
2037 Py_DECREF(v);
2038 return NULL;
2039 }
Fred Drake699f3522000-06-29 21:12:41 +00002040
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002042}
2043
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002044/* POSIX methods */
2045
Guido van Rossum94f6f721999-01-06 18:42:14 +00002046
2047static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002048posix_do_stat(char *function_name, path_t *path,
2049 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002050{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002051 STRUCT_STAT st;
2052 int result;
2053
2054#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2055 if (follow_symlinks_specified(function_name, follow_symlinks))
2056 return NULL;
2057#endif
2058
2059 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2060 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2061 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2062 return NULL;
2063
2064 Py_BEGIN_ALLOW_THREADS
2065 if (path->fd != -1)
2066 result = FSTAT(path->fd, &st);
2067 else
2068#ifdef MS_WINDOWS
2069 if (path->wide) {
2070 if (follow_symlinks)
2071 result = win32_stat_w(path->wide, &st);
2072 else
2073 result = win32_lstat_w(path->wide, &st);
2074 }
2075 else
2076#endif
2077#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2078 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2079 result = LSTAT(path->narrow, &st);
2080 else
2081#endif
2082#ifdef HAVE_FSTATAT
2083 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2084 result = fstatat(dir_fd, path->narrow, &st,
2085 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2086 else
2087#endif
2088 result = STAT(path->narrow, &st);
2089 Py_END_ALLOW_THREADS
2090
Victor Stinner292c8352012-10-30 02:17:38 +01002091 if (result != 0) {
2092 return path_error(path);
2093 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002094
2095 return _pystat_fromstructstat(&st);
2096}
2097
2098PyDoc_STRVAR(posix_stat__doc__,
2099"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2100Perform a stat system call on the given path.\n\
2101\n\
2102path may be specified as either a string or as an open file descriptor.\n\
2103\n\
2104If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2105 and path should be relative; path will then be relative to that directory.\n\
2106 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2107 it will raise a NotImplementedError.\n\
2108If follow_symlinks is False, and the last element of the path is a symbolic\n\
2109 link, stat will examine the symbolic link itself instead of the file the\n\
2110 link points to.\n\
2111It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2112 an open file descriptor.");
2113
2114static PyObject *
2115posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2116{
2117 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2118 path_t path;
2119 int dir_fd = DEFAULT_DIR_FD;
2120 int follow_symlinks = 1;
2121 PyObject *return_value;
2122
2123 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002124 path.function_name = "stat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002125 path.allow_fd = 1;
2126 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2127 path_converter, &path,
2128#ifdef HAVE_FSTATAT
2129 dir_fd_converter, &dir_fd,
2130#else
2131 dir_fd_unavailable, &dir_fd,
2132#endif
2133 &follow_symlinks))
2134 return NULL;
2135 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2136 path_cleanup(&path);
2137 return return_value;
2138}
2139
2140PyDoc_STRVAR(posix_lstat__doc__,
2141"lstat(path, *, dir_fd=None) -> stat result\n\n\
2142Like stat(), but do not follow symbolic links.\n\
2143Equivalent to stat(path, follow_symlinks=False).");
2144
2145static PyObject *
2146posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2147{
2148 static char *keywords[] = {"path", "dir_fd", NULL};
2149 path_t path;
2150 int dir_fd = DEFAULT_DIR_FD;
2151 int follow_symlinks = 0;
2152 PyObject *return_value;
2153
2154 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002155 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002156 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2157 path_converter, &path,
2158#ifdef HAVE_FSTATAT
2159 dir_fd_converter, &dir_fd
2160#else
2161 dir_fd_unavailable, &dir_fd
2162#endif
2163 ))
2164 return NULL;
2165 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2166 path_cleanup(&path);
2167 return return_value;
2168}
2169
2170PyDoc_STRVAR(posix_access__doc__,
2171"access(path, mode, *, dir_fd=None, effective_ids=False,\
2172 follow_symlinks=True)\n\n\
2173Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2174False otherwise.\n\
2175\n\
2176If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2177 and path should be relative; path will then be relative to that directory.\n\
2178If effective_ids is True, access will use the effective uid/gid instead of\n\
2179 the real uid/gid.\n\
2180If follow_symlinks is False, and the last element of the path is a symbolic\n\
2181 link, access will examine the symbolic link itself instead of the file the\n\
2182 link points to.\n\
2183dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2184 on your platform. If they are unavailable, using them will raise a\n\
2185 NotImplementedError.\n\
2186\n\
2187Note that most operations will use the effective uid/gid, therefore this\n\
2188 routine can be used in a suid/sgid environment to test if the invoking user\n\
2189 has the specified access to the path.\n\
2190The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2191 of R_OK, W_OK, and X_OK.");
2192
2193static PyObject *
2194posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2195{
2196 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2197 "follow_symlinks", NULL};
2198 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002199 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002200 int dir_fd = DEFAULT_DIR_FD;
2201 int effective_ids = 0;
2202 int follow_symlinks = 1;
2203 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002204
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002205#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002206 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002207#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002208 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002209#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002210
2211 memset(&path, 0, sizeof(path));
2212 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2213 path_converter, &path, &mode,
2214#ifdef HAVE_FACCESSAT
2215 dir_fd_converter, &dir_fd,
2216#else
2217 dir_fd_unavailable, &dir_fd,
2218#endif
2219 &effective_ids, &follow_symlinks))
2220 return NULL;
2221
2222#ifndef HAVE_FACCESSAT
2223 if (follow_symlinks_specified("access", follow_symlinks))
2224 goto exit;
2225
2226 if (effective_ids) {
2227 argument_unavailable_error("access", "effective_ids");
2228 goto exit;
2229 }
2230#endif
2231
2232#ifdef MS_WINDOWS
2233 Py_BEGIN_ALLOW_THREADS
2234 if (path.wide != NULL)
2235 attr = GetFileAttributesW(path.wide);
2236 else
2237 attr = GetFileAttributesA(path.narrow);
2238 Py_END_ALLOW_THREADS
2239
2240 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002241 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002242 * * we didn't get a -1, and
2243 * * write access wasn't requested,
2244 * * or the file isn't read-only,
2245 * * or it's a directory.
2246 * (Directories cannot be read-only on Windows.)
2247 */
2248 return_value = PyBool_FromLong(
2249 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002250 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002251 !(attr & FILE_ATTRIBUTE_READONLY) ||
2252 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2253#else
2254
2255 Py_BEGIN_ALLOW_THREADS
2256#ifdef HAVE_FACCESSAT
2257 if ((dir_fd != DEFAULT_DIR_FD) ||
2258 effective_ids ||
2259 !follow_symlinks) {
2260 int flags = 0;
2261 if (!follow_symlinks)
2262 flags |= AT_SYMLINK_NOFOLLOW;
2263 if (effective_ids)
2264 flags |= AT_EACCESS;
2265 result = faccessat(dir_fd, path.narrow, mode, flags);
2266 }
2267 else
2268#endif
2269 result = access(path.narrow, mode);
2270 Py_END_ALLOW_THREADS
2271 return_value = PyBool_FromLong(!result);
2272#endif
2273
2274#ifndef HAVE_FACCESSAT
2275exit:
2276#endif
2277 path_cleanup(&path);
2278 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002279}
2280
Guido van Rossumd371ff11999-01-25 16:12:23 +00002281#ifndef F_OK
2282#define F_OK 0
2283#endif
2284#ifndef R_OK
2285#define R_OK 4
2286#endif
2287#ifndef W_OK
2288#define W_OK 2
2289#endif
2290#ifndef X_OK
2291#define X_OK 1
2292#endif
2293
2294#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002295PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002296"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002297Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002298
2299static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002300posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002301{
Victor Stinner8c62be82010-05-06 00:08:46 +00002302 int id;
2303 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002304
Victor Stinner8c62be82010-05-06 00:08:46 +00002305 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2306 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002307
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002308#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002309 /* file descriptor 0 only, the default input device (stdin) */
2310 if (id == 0) {
2311 ret = ttyname();
2312 }
2313 else {
2314 ret = NULL;
2315 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002316#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002317 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002318#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002319 if (ret == NULL)
2320 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002321 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002322}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002323#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002324
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002325#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002326PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002327"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002328Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002329
2330static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002331posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002332{
Victor Stinner8c62be82010-05-06 00:08:46 +00002333 char *ret;
2334 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002335
Greg Wardb48bc172000-03-01 21:51:56 +00002336#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002337 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002338#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002339 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002340#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002341 if (ret == NULL)
2342 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002343 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002344}
2345#endif
2346
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002347PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002348"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002349Change the current working directory to the specified path.\n\
2350\n\
2351path may always be specified as a string.\n\
2352On some platforms, path may also be specified as an open file descriptor.\n\
2353 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002354
Barry Warsaw53699e91996-12-10 23:23:01 +00002355static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002356posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002357{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002358 path_t path;
2359 int result;
2360 PyObject *return_value = NULL;
2361 static char *keywords[] = {"path", NULL};
2362
2363 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002364 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002365#ifdef HAVE_FCHDIR
2366 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002367#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002368 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2369 path_converter, &path
2370 ))
2371 return NULL;
2372
2373 Py_BEGIN_ALLOW_THREADS
2374#ifdef MS_WINDOWS
2375 if (path.wide)
2376 result = win32_wchdir(path.wide);
2377 else
2378 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002379 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002380#else
2381#ifdef HAVE_FCHDIR
2382 if (path.fd != -1)
2383 result = fchdir(path.fd);
2384 else
2385#endif
2386 result = chdir(path.narrow);
2387#endif
2388 Py_END_ALLOW_THREADS
2389
2390 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002391 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002392 goto exit;
2393 }
2394
2395 return_value = Py_None;
2396 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002397
Larry Hastings9cf065c2012-06-22 16:30:09 -07002398exit:
2399 path_cleanup(&path);
2400 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002401}
2402
Fred Drake4d1e64b2002-04-15 19:40:07 +00002403#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002404PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002405"fchdir(fd)\n\n\
2406Change to the directory of the given file descriptor. fd must be\n\
2407opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002408
2409static PyObject *
2410posix_fchdir(PyObject *self, PyObject *fdobj)
2411{
Victor Stinner8c62be82010-05-06 00:08:46 +00002412 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002413}
2414#endif /* HAVE_FCHDIR */
2415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002416
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002417PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002418"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2419Change the access permissions of a file.\n\
2420\n\
2421path may always be specified as a string.\n\
2422On some platforms, path may also be specified as an open file descriptor.\n\
2423 If this functionality is unavailable, using it raises an exception.\n\
2424If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2425 and path should be relative; path will then be relative to that directory.\n\
2426If follow_symlinks is False, and the last element of the path is a symbolic\n\
2427 link, chmod will modify the symbolic link itself instead of the file the\n\
2428 link points to.\n\
2429It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2430 an open file descriptor.\n\
2431dir_fd and follow_symlinks may not be implemented on your platform.\n\
2432 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002433
Barry Warsaw53699e91996-12-10 23:23:01 +00002434static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002435posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002436{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002437 path_t path;
2438 int mode;
2439 int dir_fd = DEFAULT_DIR_FD;
2440 int follow_symlinks = 1;
2441 int result;
2442 PyObject *return_value = NULL;
2443 static char *keywords[] = {"path", "mode", "dir_fd",
2444 "follow_symlinks", NULL};
2445
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002446#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002447 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002448#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002449
Larry Hastings9cf065c2012-06-22 16:30:09 -07002450#ifdef HAVE_FCHMODAT
2451 int fchmodat_nofollow_unsupported = 0;
2452#endif
2453
2454 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002455 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002456#ifdef HAVE_FCHMOD
2457 path.allow_fd = 1;
2458#endif
2459 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2460 path_converter, &path,
2461 &mode,
2462#ifdef HAVE_FCHMODAT
2463 dir_fd_converter, &dir_fd,
2464#else
2465 dir_fd_unavailable, &dir_fd,
2466#endif
2467 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002468 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002469
2470#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2471 if (follow_symlinks_specified("chmod", follow_symlinks))
2472 goto exit;
2473#endif
2474
2475#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002476 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002477 if (path.wide)
2478 attr = GetFileAttributesW(path.wide);
2479 else
2480 attr = GetFileAttributesA(path.narrow);
2481 if (attr == 0xFFFFFFFF)
2482 result = 0;
2483 else {
2484 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002485 attr &= ~FILE_ATTRIBUTE_READONLY;
2486 else
2487 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002488 if (path.wide)
2489 result = SetFileAttributesW(path.wide, attr);
2490 else
2491 result = SetFileAttributesA(path.narrow, attr);
2492 }
2493 Py_END_ALLOW_THREADS
2494
2495 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002496 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002497 goto exit;
2498 }
2499#else /* MS_WINDOWS */
2500 Py_BEGIN_ALLOW_THREADS
2501#ifdef HAVE_FCHMOD
2502 if (path.fd != -1)
2503 result = fchmod(path.fd, mode);
2504 else
2505#endif
2506#ifdef HAVE_LCHMOD
2507 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2508 result = lchmod(path.narrow, mode);
2509 else
2510#endif
2511#ifdef HAVE_FCHMODAT
2512 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2513 /*
2514 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2515 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002516 * and then says it isn't implemented yet.
2517 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002518 *
2519 * Once it is supported, os.chmod will automatically
2520 * support dir_fd and follow_symlinks=False. (Hopefully.)
2521 * Until then, we need to be careful what exception we raise.
2522 */
2523 result = fchmodat(dir_fd, path.narrow, mode,
2524 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2525 /*
2526 * But wait! We can't throw the exception without allowing threads,
2527 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2528 */
2529 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002530 result &&
2531 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2532 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002533 }
2534 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002535#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002536 result = chmod(path.narrow, mode);
2537 Py_END_ALLOW_THREADS
2538
2539 if (result) {
2540#ifdef HAVE_FCHMODAT
2541 if (fchmodat_nofollow_unsupported) {
2542 if (dir_fd != DEFAULT_DIR_FD)
2543 dir_fd_and_follow_symlinks_invalid("chmod",
2544 dir_fd, follow_symlinks);
2545 else
2546 follow_symlinks_specified("chmod", follow_symlinks);
2547 }
2548 else
2549#endif
Victor Stinner292c8352012-10-30 02:17:38 +01002550 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002551 goto exit;
2552 }
2553#endif
2554
2555 Py_INCREF(Py_None);
2556 return_value = Py_None;
2557exit:
2558 path_cleanup(&path);
2559 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002560}
2561
Larry Hastings9cf065c2012-06-22 16:30:09 -07002562
Christian Heimes4e30a842007-11-30 22:12:06 +00002563#ifdef HAVE_FCHMOD
2564PyDoc_STRVAR(posix_fchmod__doc__,
2565"fchmod(fd, mode)\n\n\
2566Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002567descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002568
2569static PyObject *
2570posix_fchmod(PyObject *self, PyObject *args)
2571{
Victor Stinner8c62be82010-05-06 00:08:46 +00002572 int fd, mode, res;
2573 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2574 return NULL;
2575 Py_BEGIN_ALLOW_THREADS
2576 res = fchmod(fd, mode);
2577 Py_END_ALLOW_THREADS
2578 if (res < 0)
2579 return posix_error();
2580 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002581}
2582#endif /* HAVE_FCHMOD */
2583
2584#ifdef HAVE_LCHMOD
2585PyDoc_STRVAR(posix_lchmod__doc__,
2586"lchmod(path, mode)\n\n\
2587Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002588affects the link itself rather than the target.\n\
2589Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002590
2591static PyObject *
2592posix_lchmod(PyObject *self, PyObject *args)
2593{
Victor Stinner292c8352012-10-30 02:17:38 +01002594 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 int i;
2596 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002597 memset(&path, 0, sizeof(path));
2598 path.function_name = "lchmod";
2599 if (!PyArg_ParseTuple(args, "O&i:lchmod",
2600 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002601 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002602 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002603 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00002604 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002605 if (res < 0) {
2606 path_error(&path);
2607 path_cleanup(&path);
2608 return NULL;
2609 }
2610 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002611 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002612}
2613#endif /* HAVE_LCHMOD */
2614
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002615
Thomas Wouterscf297e42007-02-23 15:07:44 +00002616#ifdef HAVE_CHFLAGS
2617PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002618"chflags(path, flags, *, follow_symlinks=True)\n\n\
2619Set file flags.\n\
2620\n\
2621If follow_symlinks is False, and the last element of the path is a symbolic\n\
2622 link, chflags will change flags on the symbolic link itself instead of the\n\
2623 file the link points to.\n\
2624follow_symlinks may not be implemented on your platform. If it is\n\
2625unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002626
2627static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002628posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002629{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002630 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002631 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632 int follow_symlinks = 1;
2633 int result;
2634 PyObject *return_value;
2635 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2636
2637 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002638 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002639 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2640 path_converter, &path,
2641 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002642 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002643
2644#ifndef HAVE_LCHFLAGS
2645 if (follow_symlinks_specified("chflags", follow_symlinks))
2646 goto exit;
2647#endif
2648
Victor Stinner8c62be82010-05-06 00:08:46 +00002649 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002650#ifdef HAVE_LCHFLAGS
2651 if (!follow_symlinks)
2652 result = lchflags(path.narrow, flags);
2653 else
2654#endif
2655 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002656 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002657
2658 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002659 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002660 goto exit;
2661 }
2662
2663 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002665
2666exit:
2667 path_cleanup(&path);
2668 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002669}
2670#endif /* HAVE_CHFLAGS */
2671
2672#ifdef HAVE_LCHFLAGS
2673PyDoc_STRVAR(posix_lchflags__doc__,
2674"lchflags(path, flags)\n\n\
2675Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002676This function will not follow symbolic links.\n\
2677Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002678
2679static PyObject *
2680posix_lchflags(PyObject *self, PyObject *args)
2681{
Victor Stinner292c8352012-10-30 02:17:38 +01002682 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 unsigned long flags;
2684 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002685 memset(&path, 0, sizeof(path));
2686 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00002687 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01002688 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00002689 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002690 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002691 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002692 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002693 if (res < 0) {
2694 path_error(&path);
2695 path_cleanup(&path);
2696 return NULL;
2697 }
2698 path_cleanup(&path);
2699 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002700}
2701#endif /* HAVE_LCHFLAGS */
2702
Martin v. Löwis244edc82001-10-04 22:44:26 +00002703#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002704PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002705"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002706Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002707
2708static PyObject *
2709posix_chroot(PyObject *self, PyObject *args)
2710{
Victor Stinner292c8352012-10-30 02:17:38 +01002711 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002712}
2713#endif
2714
Guido van Rossum21142a01999-01-08 21:05:37 +00002715#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002716PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002717"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002718force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002719
2720static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002721posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002722{
Stefan Krah0e803b32010-11-26 16:16:47 +00002723 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002724}
2725#endif /* HAVE_FSYNC */
2726
Ross Lagerwall7807c352011-03-17 20:20:30 +02002727#ifdef HAVE_SYNC
2728PyDoc_STRVAR(posix_sync__doc__,
2729"sync()\n\n\
2730Force write of everything to disk.");
2731
2732static PyObject *
2733posix_sync(PyObject *self, PyObject *noargs)
2734{
2735 Py_BEGIN_ALLOW_THREADS
2736 sync();
2737 Py_END_ALLOW_THREADS
2738 Py_RETURN_NONE;
2739}
2740#endif
2741
Guido van Rossum21142a01999-01-08 21:05:37 +00002742#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002743
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002744#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002745extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2746#endif
2747
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002748PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002749"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002750force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002751 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002752
2753static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002754posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002755{
Stefan Krah0e803b32010-11-26 16:16:47 +00002756 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002757}
2758#endif /* HAVE_FDATASYNC */
2759
2760
Fredrik Lundh10723342000-07-10 16:38:09 +00002761#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002762PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002763"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2764Change the owner and group id of path to the numeric uid and gid.\n\
2765\n\
2766path may always be specified as a string.\n\
2767On some platforms, path may also be specified as an open file descriptor.\n\
2768 If this functionality is unavailable, using it raises an exception.\n\
2769If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2770 and path should be relative; path will then be relative to that directory.\n\
2771If follow_symlinks is False, and the last element of the path is a symbolic\n\
2772 link, chown will modify the symbolic link itself instead of the file the\n\
2773 link points to.\n\
2774It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2775 an open file descriptor.\n\
2776dir_fd and follow_symlinks may not be implemented on your platform.\n\
2777 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002778
Barry Warsaw53699e91996-12-10 23:23:01 +00002779static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002781{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782 path_t path;
2783 long uid_l, gid_l;
2784 uid_t uid;
2785 gid_t gid;
2786 int dir_fd = DEFAULT_DIR_FD;
2787 int follow_symlinks = 1;
2788 int result;
2789 PyObject *return_value = NULL;
2790 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2791 "follow_symlinks", NULL};
2792
2793 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002794 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795#ifdef HAVE_FCHOWN
2796 path.allow_fd = 1;
2797#endif
2798 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2799 path_converter, &path,
2800 &uid_l, &gid_l,
2801#ifdef HAVE_FCHOWNAT
2802 dir_fd_converter, &dir_fd,
2803#else
2804 dir_fd_unavailable, &dir_fd,
2805#endif
2806 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002807 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808
2809#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2810 if (follow_symlinks_specified("chown", follow_symlinks))
2811 goto exit;
2812#endif
2813 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2814 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2815 goto exit;
2816
2817#ifdef __APPLE__
2818 /*
2819 * This is for Mac OS X 10.3, which doesn't have lchown.
2820 * (But we still have an lchown symbol because of weak-linking.)
2821 * It doesn't have fchownat either. So there's no possibility
2822 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02002823 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 if ((!follow_symlinks) && (lchown == NULL)) {
2825 follow_symlinks_specified("chown", follow_symlinks);
2826 goto exit;
2827 }
2828#endif
2829
Victor Stinner8c62be82010-05-06 00:08:46 +00002830 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 uid = (uid_t)uid_l;
2832 gid = (uid_t)gid_l;
2833#ifdef HAVE_FCHOWN
2834 if (path.fd != -1)
2835 result = fchown(path.fd, uid, gid);
2836 else
2837#endif
2838#ifdef HAVE_LCHOWN
2839 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2840 result = lchown(path.narrow, uid, gid);
2841 else
2842#endif
2843#ifdef HAVE_FCHOWNAT
2844 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
2845 result = fchownat(dir_fd, path.narrow, uid, gid,
2846 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2847 else
2848#endif
2849 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002850 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002851
2852 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002853 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002854 goto exit;
2855 }
2856
2857 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002858 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859
2860exit:
2861 path_cleanup(&path);
2862 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002863}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002864#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002865
Christian Heimes4e30a842007-11-30 22:12:06 +00002866#ifdef HAVE_FCHOWN
2867PyDoc_STRVAR(posix_fchown__doc__,
2868"fchown(fd, uid, gid)\n\n\
2869Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002870fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002871
2872static PyObject *
2873posix_fchown(PyObject *self, PyObject *args)
2874{
Victor Stinner8c62be82010-05-06 00:08:46 +00002875 int fd;
2876 long uid, gid;
2877 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002878 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002879 return NULL;
2880 Py_BEGIN_ALLOW_THREADS
2881 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2882 Py_END_ALLOW_THREADS
2883 if (res < 0)
2884 return posix_error();
2885 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002886}
2887#endif /* HAVE_FCHOWN */
2888
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002889#ifdef HAVE_LCHOWN
2890PyDoc_STRVAR(posix_lchown__doc__,
2891"lchown(path, uid, gid)\n\n\
2892Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002893This function will not follow symbolic links.\n\
2894Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002895
2896static PyObject *
2897posix_lchown(PyObject *self, PyObject *args)
2898{
Victor Stinner292c8352012-10-30 02:17:38 +01002899 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002900 long uid, gid;
2901 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002902 memset(&path, 0, sizeof(path));
2903 path.function_name = "lchown";
Victor Stinner8c62be82010-05-06 00:08:46 +00002904 if (!PyArg_ParseTuple(args, "O&ll:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01002905 path_converter, &path,
Victor Stinner8c62be82010-05-06 00:08:46 +00002906 &uid, &gid))
2907 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002908 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002909 res = lchown(path.narrow, (uid_t) uid, (gid_t) gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002910 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002911 if (res < 0) {
2912 path_error(&path);
2913 path_cleanup(&path);
2914 return NULL;
2915 }
2916 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002917 Py_INCREF(Py_None);
2918 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002919}
2920#endif /* HAVE_LCHOWN */
2921
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002922
Guido van Rossum36bc6801995-06-14 22:54:23 +00002923#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002924static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002925posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002926{
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 char buf[1026];
2928 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002929
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002930#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002931 if (!use_bytes) {
2932 wchar_t wbuf[1026];
2933 wchar_t *wbuf2 = wbuf;
2934 PyObject *resobj;
2935 DWORD len;
2936 Py_BEGIN_ALLOW_THREADS
2937 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2938 /* If the buffer is large enough, len does not include the
2939 terminating \0. If the buffer is too small, len includes
2940 the space needed for the terminator. */
2941 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2942 wbuf2 = malloc(len * sizeof(wchar_t));
2943 if (wbuf2)
2944 len = GetCurrentDirectoryW(len, wbuf2);
2945 }
2946 Py_END_ALLOW_THREADS
2947 if (!wbuf2) {
2948 PyErr_NoMemory();
2949 return NULL;
2950 }
2951 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002952 if (wbuf2 != wbuf)
2953 free(wbuf2);
2954 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00002955 }
2956 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01002957 if (wbuf2 != wbuf)
2958 free(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00002959 return resobj;
2960 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01002961
2962 if (win32_warn_bytes_api())
2963 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002964#endif
2965
Victor Stinner8c62be82010-05-06 00:08:46 +00002966 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002967 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00002968 Py_END_ALLOW_THREADS
2969 if (res == NULL)
2970 return posix_error();
2971 if (use_bytes)
2972 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002973 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002974}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002975
2976PyDoc_STRVAR(posix_getcwd__doc__,
2977"getcwd() -> path\n\n\
2978Return a unicode string representing the current working directory.");
2979
2980static PyObject *
2981posix_getcwd_unicode(PyObject *self)
2982{
2983 return posix_getcwd(0);
2984}
2985
2986PyDoc_STRVAR(posix_getcwdb__doc__,
2987"getcwdb() -> path\n\n\
2988Return a bytes string representing the current working directory.");
2989
2990static PyObject *
2991posix_getcwd_bytes(PyObject *self)
2992{
2993 return posix_getcwd(1);
2994}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002995#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002996
Larry Hastings9cf065c2012-06-22 16:30:09 -07002997#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
2998#define HAVE_LINK 1
2999#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003000
Guido van Rossumb6775db1994-08-01 11:34:53 +00003001#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003002PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3004Create a hard link to a file.\n\
3005\n\
3006If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3007 descriptor open to a directory, and the respective path string (src or dst)\n\
3008 should be relative; the path will then be relative to that directory.\n\
3009If follow_symlinks is False, and the last element of src is a symbolic\n\
3010 link, link will create a link to the symbolic link itself instead of the\n\
3011 file the link points to.\n\
3012src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3013 platform. If they are unavailable, using them will raise a\n\
3014 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003015
Barry Warsaw53699e91996-12-10 23:23:01 +00003016static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003017posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003018{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003019 path_t src, dst;
3020 int src_dir_fd = DEFAULT_DIR_FD;
3021 int dst_dir_fd = DEFAULT_DIR_FD;
3022 int follow_symlinks = 1;
3023 PyObject *return_value = NULL;
3024 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3025 "follow_symlinks", NULL};
3026#ifdef MS_WINDOWS
3027 BOOL result;
3028#else
3029 int result;
3030#endif
3031
3032 memset(&src, 0, sizeof(src));
3033 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003034 src.function_name = "link";
3035 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003036 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3037 path_converter, &src,
3038 path_converter, &dst,
3039 dir_fd_converter, &src_dir_fd,
3040 dir_fd_converter, &dst_dir_fd,
3041 &follow_symlinks))
3042 return NULL;
3043
3044#ifndef HAVE_LINKAT
3045 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3046 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3047 goto exit;
3048 }
3049#endif
3050
3051 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3052 PyErr_SetString(PyExc_NotImplementedError,
3053 "link: src and dst must be the same type");
3054 goto exit;
3055 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003056
Brian Curtin1b9df392010-11-24 20:24:31 +00003057#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003058 Py_BEGIN_ALLOW_THREADS
3059 if (src.wide)
3060 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3061 else
3062 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3063 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003064
Larry Hastings9cf065c2012-06-22 16:30:09 -07003065 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003066 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003067 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003068 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003069#else
3070 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003071#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003072 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3073 (dst_dir_fd != DEFAULT_DIR_FD) ||
3074 (!follow_symlinks))
3075 result = linkat(src_dir_fd, src.narrow,
3076 dst_dir_fd, dst.narrow,
3077 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3078 else
3079#endif
3080 result = link(src.narrow, dst.narrow);
3081 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003082
Larry Hastings9cf065c2012-06-22 16:30:09 -07003083 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003084 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003085 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003086 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087#endif
3088
3089 return_value = Py_None;
3090 Py_INCREF(Py_None);
3091
3092exit:
3093 path_cleanup(&src);
3094 path_cleanup(&dst);
3095 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003096}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003097#endif
3098
Brian Curtin1b9df392010-11-24 20:24:31 +00003099
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003100
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003101PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003102"listdir(path='.') -> list_of_filenames\n\n\
3103Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003104The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003105entries '.' and '..' even if they are present in the directory.\n\
3106\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003107path can be specified as either str or bytes. If path is bytes,\n\
3108 the filenames returned will also be bytes; in all other circumstances\n\
3109 the filenames returned will be str.\n\
3110On some platforms, path may also be specified as an open file descriptor;\n\
3111 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003112 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003113
Barry Warsaw53699e91996-12-10 23:23:01 +00003114static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003115posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003116{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003117 path_t path;
3118 PyObject *list = NULL;
3119 static char *keywords[] = {"path", NULL};
3120 int fd = -1;
3121
3122#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3123 PyObject *v;
3124 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3125 BOOL result;
3126 WIN32_FIND_DATA FileData;
3127 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3128 char *bufptr = namebuf;
3129 /* only claim to have space for MAX_PATH */
3130 Py_ssize_t len = sizeof(namebuf)-5;
3131 PyObject *po = NULL;
3132 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003133#else
3134 PyObject *v;
3135 DIR *dirp = NULL;
3136 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003137 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003138#endif
3139
3140 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003141 path.function_name = "listdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003142 path.nullable = 1;
3143#ifdef HAVE_FDOPENDIR
3144 path.allow_fd = 1;
3145 path.fd = -1;
3146#endif
3147 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3148 path_converter, &path
3149 ))
3150 return NULL;
3151
Victor Stinner8c62be82010-05-06 00:08:46 +00003152 /* XXX Should redo this putting the (now four) versions of opendir
3153 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003154#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003155 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003158
Larry Hastings9cf065c2012-06-22 16:30:09 -07003159 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003160 po_wchars = L".";
3161 len = 1;
3162 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003163 po_wchars = path.wide;
3164 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003165 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003166 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003167 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3168 if (!wnamebuf) {
3169 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003170 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003172 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003174 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003175 if (wch != L'/' && wch != L'\\' && wch != L':')
3176 wnamebuf[len++] = L'\\';
3177 wcscpy(wnamebuf + len, L"*.*");
3178 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003179 if ((list = PyList_New(0)) == NULL) {
3180 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003181 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003182 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003183 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003184 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003185 if (hFindFile == INVALID_HANDLE_VALUE) {
3186 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187 if (error == ERROR_FILE_NOT_FOUND)
3188 goto exit;
3189 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003190 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003191 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003192 }
3193 do {
3194 /* Skip over . and .. */
3195 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3196 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197 v = PyUnicode_FromWideChar(wFileData.cFileName,
3198 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003199 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003200 Py_DECREF(list);
3201 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003202 break;
3203 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003204 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003205 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003206 Py_DECREF(list);
3207 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003208 break;
3209 }
3210 Py_DECREF(v);
3211 }
3212 Py_BEGIN_ALLOW_THREADS
3213 result = FindNextFileW(hFindFile, &wFileData);
3214 Py_END_ALLOW_THREADS
3215 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3216 it got to the end of the directory. */
3217 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003218 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003219 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003220 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003221 }
3222 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003223
Larry Hastings9cf065c2012-06-22 16:30:09 -07003224 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003225 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003226 strcpy(namebuf, path.narrow);
3227 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003228 if (len > 0) {
3229 char ch = namebuf[len-1];
3230 if (ch != SEP && ch != ALTSEP && ch != ':')
3231 namebuf[len++] = '/';
3232 strcpy(namebuf + len, "*.*");
3233 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003234
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003237
Antoine Pitroub73caab2010-08-09 23:39:31 +00003238 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003240 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 if (hFindFile == INVALID_HANDLE_VALUE) {
3242 int error = GetLastError();
3243 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003244 goto exit;
3245 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003246 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003247 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003248 }
3249 do {
3250 /* Skip over . and .. */
3251 if (strcmp(FileData.cFileName, ".") != 0 &&
3252 strcmp(FileData.cFileName, "..") != 0) {
3253 v = PyBytes_FromString(FileData.cFileName);
3254 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003255 Py_DECREF(list);
3256 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 break;
3258 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003259 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003260 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003261 Py_DECREF(list);
3262 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003263 break;
3264 }
3265 Py_DECREF(v);
3266 }
3267 Py_BEGIN_ALLOW_THREADS
3268 result = FindNextFile(hFindFile, &FileData);
3269 Py_END_ALLOW_THREADS
3270 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3271 it got to the end of the directory. */
3272 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003273 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003274 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003275 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003276 }
3277 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003278
Larry Hastings9cf065c2012-06-22 16:30:09 -07003279exit:
3280 if (hFindFile != INVALID_HANDLE_VALUE) {
3281 if (FindClose(hFindFile) == FALSE) {
3282 if (list != NULL) {
3283 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003284 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003285 }
3286 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003288 if (wnamebuf)
3289 free(wnamebuf);
3290 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003291
Larry Hastings9cf065c2012-06-22 16:30:09 -07003292 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003293
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003294#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003295
Victor Stinner8c62be82010-05-06 00:08:46 +00003296 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003297#ifdef HAVE_FDOPENDIR
3298 if (path.fd != -1) {
3299 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003300 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003301 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003302 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003303
3304 if (fd == -1) {
3305 list = posix_error();
3306 goto exit;
3307 }
3308
Larry Hastingsfdaea062012-06-25 04:42:23 -07003309 return_str = 1;
3310
Larry Hastings9cf065c2012-06-22 16:30:09 -07003311 Py_BEGIN_ALLOW_THREADS
3312 dirp = fdopendir(fd);
3313 Py_END_ALLOW_THREADS
3314 }
3315 else
3316#endif
3317 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003318 char *name;
3319 if (path.narrow) {
3320 name = path.narrow;
3321 /* only return bytes if they specified a bytes object */
3322 return_str = !(PyBytes_Check(path.object));
3323 }
3324 else {
3325 name = ".";
3326 return_str = 1;
3327 }
3328
Larry Hastings9cf065c2012-06-22 16:30:09 -07003329 Py_BEGIN_ALLOW_THREADS
3330 dirp = opendir(name);
3331 Py_END_ALLOW_THREADS
3332 }
3333
3334 if (dirp == NULL) {
Victor Stinner292c8352012-10-30 02:17:38 +01003335 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003336 goto exit;
3337 }
3338 if ((list = PyList_New(0)) == NULL) {
3339 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 }
3341 for (;;) {
3342 errno = 0;
3343 Py_BEGIN_ALLOW_THREADS
3344 ep = readdir(dirp);
3345 Py_END_ALLOW_THREADS
3346 if (ep == NULL) {
3347 if (errno == 0) {
3348 break;
3349 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003350 Py_DECREF(list);
Victor Stinner292c8352012-10-30 02:17:38 +01003351 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003352 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003353 }
3354 }
3355 if (ep->d_name[0] == '.' &&
3356 (NAMLEN(ep) == 1 ||
3357 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3358 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003359 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003360 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3361 else
3362 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003365 break;
3366 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003367 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003369 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 break;
3371 }
3372 Py_DECREF(v);
3373 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003374
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375exit:
3376 if (dirp != NULL) {
3377 Py_BEGIN_ALLOW_THREADS
3378 if (fd > -1)
3379 rewinddir(dirp);
3380 closedir(dirp);
3381 Py_END_ALLOW_THREADS
3382 }
3383
3384 path_cleanup(&path);
3385
3386 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003387
Tim Peters0bb44a42000-09-15 07:44:49 +00003388#endif /* which OS */
3389} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003390
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003391#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003392/* A helper function for abspath on win32 */
3393static PyObject *
3394posix__getfullpathname(PyObject *self, PyObject *args)
3395{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003396 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003397 char outbuf[MAX_PATH*2];
3398 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003399 PyObject *po;
3400
3401 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3402 {
3403 wchar_t *wpath;
3404 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3405 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003406 DWORD result;
3407 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003408
3409 wpath = PyUnicode_AsUnicode(po);
3410 if (wpath == NULL)
3411 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003413 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003414 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003415 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003416 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003417 if (!woutbufp)
3418 return PyErr_NoMemory();
3419 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3420 }
3421 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003422 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003424 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 if (woutbufp != woutbuf)
3426 free(woutbufp);
3427 return v;
3428 }
3429 /* Drop the argument parsing error as narrow strings
3430 are also valid. */
3431 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003432
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003433 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3434 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003435 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003436 if (win32_warn_bytes_api())
3437 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003438 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 outbuf, &temp)) {
3440 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003441 return NULL;
3442 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003443 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3444 return PyUnicode_Decode(outbuf, strlen(outbuf),
3445 Py_FileSystemDefaultEncoding, NULL);
3446 }
3447 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003448} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003449
Brian Curtind25aef52011-06-13 15:16:04 -05003450
Brian Curtinf5e76d02010-11-24 13:14:05 +00003451
Brian Curtind40e6f72010-07-08 21:39:08 +00003452/* A helper function for samepath on windows */
3453static PyObject *
3454posix__getfinalpathname(PyObject *self, PyObject *args)
3455{
3456 HANDLE hFile;
3457 int buf_size;
3458 wchar_t *target_path;
3459 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003460 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003461 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003462
Victor Stinnereb5657a2011-09-30 01:44:27 +02003463 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003464 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003465 path = PyUnicode_AsUnicode(po);
3466 if (path == NULL)
3467 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003468
3469 if(!check_GetFinalPathNameByHandle()) {
3470 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3471 NotImplementedError. */
3472 return PyErr_Format(PyExc_NotImplementedError,
3473 "GetFinalPathNameByHandle not available on this platform");
3474 }
3475
3476 hFile = CreateFileW(
3477 path,
3478 0, /* desired access */
3479 0, /* share mode */
3480 NULL, /* security attributes */
3481 OPEN_EXISTING,
3482 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3483 FILE_FLAG_BACKUP_SEMANTICS,
3484 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003485
Victor Stinnereb5657a2011-09-30 01:44:27 +02003486 if(hFile == INVALID_HANDLE_VALUE)
3487 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003488
3489 /* We have a good handle to the target, use it to determine the
3490 target path name. */
3491 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3492
3493 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003494 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003495
3496 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3497 if(!target_path)
3498 return PyErr_NoMemory();
3499
3500 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3501 buf_size, VOLUME_NAME_DOS);
3502 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003503 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003504
3505 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003506 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003507
3508 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003509 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003510 free(target_path);
3511 return result;
3512
3513} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003514
Brian Curtin95d028f2011-06-09 09:10:38 -05003515PyDoc_STRVAR(posix__isdir__doc__,
3516"Return true if the pathname refers to an existing directory.");
3517
Brian Curtin9c669cc2011-06-08 18:17:18 -05003518static PyObject *
3519posix__isdir(PyObject *self, PyObject *args)
3520{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003521 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003522 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003523 DWORD attributes;
3524
3525 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003526 wchar_t *wpath = PyUnicode_AsUnicode(po);
3527 if (wpath == NULL)
3528 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003529
3530 attributes = GetFileAttributesW(wpath);
3531 if (attributes == INVALID_FILE_ATTRIBUTES)
3532 Py_RETURN_FALSE;
3533 goto check;
3534 }
3535 /* Drop the argument parsing error as narrow strings
3536 are also valid. */
3537 PyErr_Clear();
3538
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003539 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003540 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003541 if (win32_warn_bytes_api())
3542 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003543 attributes = GetFileAttributesA(path);
3544 if (attributes == INVALID_FILE_ATTRIBUTES)
3545 Py_RETURN_FALSE;
3546
3547check:
3548 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3549 Py_RETURN_TRUE;
3550 else
3551 Py_RETURN_FALSE;
3552}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003553#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003554
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003555PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3557Create a directory.\n\
3558\n\
3559If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3560 and path should be relative; path will then be relative to that directory.\n\
3561dir_fd may not be implemented on your platform.\n\
3562 If it is unavailable, using it will raise a NotImplementedError.\n\
3563\n\
3564The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003565
Barry Warsaw53699e91996-12-10 23:23:01 +00003566static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003567posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003568{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 int dir_fd = DEFAULT_DIR_FD;
3572 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3573 PyObject *return_value = NULL;
3574 int result;
3575
3576 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003577 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3579 path_converter, &path, &mode,
3580#ifdef HAVE_MKDIRAT
3581 dir_fd_converter, &dir_fd
3582#else
3583 dir_fd_unavailable, &dir_fd
3584#endif
3585 ))
3586 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003587
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003588#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590 if (path.wide)
3591 result = CreateDirectoryW(path.wide, NULL);
3592 else
3593 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003595
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003597 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 goto exit;
3599 }
3600#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003601 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003602#if HAVE_MKDIRAT
3603 if (dir_fd != DEFAULT_DIR_FD)
3604 result = mkdirat(dir_fd, path.narrow, mode);
3605 else
3606#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003607#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003608 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003609#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003611#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01003614 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 goto exit;
3616 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003617#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618 return_value = Py_None;
3619 Py_INCREF(Py_None);
3620exit:
3621 path_cleanup(&path);
3622 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003623}
3624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003625
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003626/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3627#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003628#include <sys/resource.h>
3629#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003630
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003631
3632#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003633PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003634"nice(inc) -> new_priority\n\n\
3635Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003636
Barry Warsaw53699e91996-12-10 23:23:01 +00003637static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003638posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003639{
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003641
Victor Stinner8c62be82010-05-06 00:08:46 +00003642 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3643 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003644
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 /* There are two flavours of 'nice': one that returns the new
3646 priority (as required by almost all standards out there) and the
3647 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3648 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003649
Victor Stinner8c62be82010-05-06 00:08:46 +00003650 If we are of the nice family that returns the new priority, we
3651 need to clear errno before the call, and check if errno is filled
3652 before calling posix_error() on a returnvalue of -1, because the
3653 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003654
Victor Stinner8c62be82010-05-06 00:08:46 +00003655 errno = 0;
3656 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003657#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 if (value == 0)
3659 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003660#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 if (value == -1 && errno != 0)
3662 /* either nice() or getpriority() returned an error */
3663 return posix_error();
3664 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003665}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003666#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003667
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003668
3669#ifdef HAVE_GETPRIORITY
3670PyDoc_STRVAR(posix_getpriority__doc__,
3671"getpriority(which, who) -> current_priority\n\n\
3672Get program scheduling priority.");
3673
3674static PyObject *
3675posix_getpriority(PyObject *self, PyObject *args)
3676{
3677 int which, who, retval;
3678
3679 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3680 return NULL;
3681 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003682 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003683 if (errno != 0)
3684 return posix_error();
3685 return PyLong_FromLong((long)retval);
3686}
3687#endif /* HAVE_GETPRIORITY */
3688
3689
3690#ifdef HAVE_SETPRIORITY
3691PyDoc_STRVAR(posix_setpriority__doc__,
3692"setpriority(which, who, prio) -> None\n\n\
3693Set program scheduling priority.");
3694
3695static PyObject *
3696posix_setpriority(PyObject *self, PyObject *args)
3697{
3698 int which, who, prio, retval;
3699
3700 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3701 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003702 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003703 if (retval == -1)
3704 return posix_error();
3705 Py_RETURN_NONE;
3706}
3707#endif /* HAVE_SETPRIORITY */
3708
3709
Barry Warsaw53699e91996-12-10 23:23:01 +00003710static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003711internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003712{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713 char *function_name = is_replace ? "replace" : "rename";
3714 path_t src;
3715 path_t dst;
3716 int src_dir_fd = DEFAULT_DIR_FD;
3717 int dst_dir_fd = DEFAULT_DIR_FD;
3718 int dir_fd_specified;
3719 PyObject *return_value = NULL;
3720 char format[24];
3721 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3722
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003723#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003724 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003725 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003726#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003727 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003728#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003729
3730 memset(&src, 0, sizeof(src));
3731 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003732 src.function_name = function_name;
3733 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003734 strcpy(format, "O&O&|$O&O&:");
3735 strcat(format, function_name);
3736 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3737 path_converter, &src,
3738 path_converter, &dst,
3739 dir_fd_converter, &src_dir_fd,
3740 dir_fd_converter, &dst_dir_fd))
3741 return NULL;
3742
3743 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3744 (dst_dir_fd != DEFAULT_DIR_FD);
3745#ifndef HAVE_RENAMEAT
3746 if (dir_fd_specified) {
3747 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
3748 goto exit;
3749 }
3750#endif
3751
3752 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3753 PyErr_Format(PyExc_ValueError,
3754 "%s: src and dst must be the same type", function_name);
3755 goto exit;
3756 }
3757
3758#ifdef MS_WINDOWS
3759 Py_BEGIN_ALLOW_THREADS
3760 if (src.wide)
3761 result = MoveFileExW(src.wide, dst.wide, flags);
3762 else
3763 result = MoveFileExA(src.narrow, dst.narrow, flags);
3764 Py_END_ALLOW_THREADS
3765
3766 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003767 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003768 goto exit;
3769 }
3770
3771#else
3772 Py_BEGIN_ALLOW_THREADS
3773#ifdef HAVE_RENAMEAT
3774 if (dir_fd_specified)
3775 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
3776 else
3777#endif
3778 result = rename(src.narrow, dst.narrow);
3779 Py_END_ALLOW_THREADS
3780
3781 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003782 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003783 goto exit;
3784 }
3785#endif
3786
3787 Py_INCREF(Py_None);
3788 return_value = Py_None;
3789exit:
3790 path_cleanup(&src);
3791 path_cleanup(&dst);
3792 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003793}
3794
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003795PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003796"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3797Rename a file or directory.\n\
3798\n\
3799If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3800 descriptor open to a directory, and the respective path string (src or dst)\n\
3801 should be relative; the path will then be relative to that directory.\n\
3802src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3803 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003804
3805static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003806posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003807{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003808 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003809}
3810
3811PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003812"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3813Rename a file or directory, overwriting the destination.\n\
3814\n\
3815If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3816 descriptor open to a directory, and the respective path string (src or dst)\n\
3817 should be relative; the path will then be relative to that directory.\n\
3818src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3819 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003820
3821static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003822posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003823{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003824 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003825}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003826
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003827PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003828"rmdir(path, *, dir_fd=None)\n\n\
3829Remove a directory.\n\
3830\n\
3831If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3832 and path should be relative; path will then be relative to that directory.\n\
3833dir_fd may not be implemented on your platform.\n\
3834 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003835
Barry Warsaw53699e91996-12-10 23:23:01 +00003836static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003837posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003838{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003839 path_t path;
3840 int dir_fd = DEFAULT_DIR_FD;
3841 static char *keywords[] = {"path", "dir_fd", NULL};
3842 int result;
3843 PyObject *return_value = NULL;
3844
3845 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003846 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003847 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
3848 path_converter, &path,
3849#ifdef HAVE_UNLINKAT
3850 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003851#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003852 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003853#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003854 ))
3855 return NULL;
3856
3857 Py_BEGIN_ALLOW_THREADS
3858#ifdef MS_WINDOWS
3859 if (path.wide)
3860 result = RemoveDirectoryW(path.wide);
3861 else
3862 result = RemoveDirectoryA(path.narrow);
3863 result = !result; /* Windows, success=1, UNIX, success=0 */
3864#else
3865#ifdef HAVE_UNLINKAT
3866 if (dir_fd != DEFAULT_DIR_FD)
3867 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
3868 else
3869#endif
3870 result = rmdir(path.narrow);
3871#endif
3872 Py_END_ALLOW_THREADS
3873
3874 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003875 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003876 goto exit;
3877 }
3878
3879 return_value = Py_None;
3880 Py_INCREF(Py_None);
3881
3882exit:
3883 path_cleanup(&path);
3884 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003885}
3886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003887
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003888#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003889PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003890"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003891Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003892
Barry Warsaw53699e91996-12-10 23:23:01 +00003893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003894posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003895{
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003897#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 wchar_t *command;
3899 if (!PyArg_ParseTuple(args, "u:system", &command))
3900 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003901
Victor Stinner8c62be82010-05-06 00:08:46 +00003902 Py_BEGIN_ALLOW_THREADS
3903 sts = _wsystem(command);
3904 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003905#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003906 PyObject *command_obj;
3907 char *command;
3908 if (!PyArg_ParseTuple(args, "O&:system",
3909 PyUnicode_FSConverter, &command_obj))
3910 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003911
Victor Stinner8c62be82010-05-06 00:08:46 +00003912 command = PyBytes_AsString(command_obj);
3913 Py_BEGIN_ALLOW_THREADS
3914 sts = system(command);
3915 Py_END_ALLOW_THREADS
3916 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003917#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003918 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003919}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003920#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003921
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003922
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003923PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003924"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003925Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003926
Barry Warsaw53699e91996-12-10 23:23:01 +00003927static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003928posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003929{
Victor Stinner8c62be82010-05-06 00:08:46 +00003930 int i;
3931 if (!PyArg_ParseTuple(args, "i:umask", &i))
3932 return NULL;
3933 i = (int)umask(i);
3934 if (i < 0)
3935 return posix_error();
3936 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003937}
3938
Brian Curtind40e6f72010-07-08 21:39:08 +00003939#ifdef MS_WINDOWS
3940
3941/* override the default DeleteFileW behavior so that directory
3942symlinks can be removed with this function, the same as with
3943Unix symlinks */
3944BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3945{
3946 WIN32_FILE_ATTRIBUTE_DATA info;
3947 WIN32_FIND_DATAW find_data;
3948 HANDLE find_data_handle;
3949 int is_directory = 0;
3950 int is_link = 0;
3951
3952 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3953 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003954
Brian Curtind40e6f72010-07-08 21:39:08 +00003955 /* Get WIN32_FIND_DATA structure for the path to determine if
3956 it is a symlink */
3957 if(is_directory &&
3958 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3959 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3960
3961 if(find_data_handle != INVALID_HANDLE_VALUE) {
3962 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3963 FindClose(find_data_handle);
3964 }
3965 }
3966 }
3967
3968 if (is_directory && is_link)
3969 return RemoveDirectoryW(lpFileName);
3970
3971 return DeleteFileW(lpFileName);
3972}
3973#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003974
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003975PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003976"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003977Remove a file (same as remove()).\n\
3978\n\
3979If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3980 and path should be relative; path will then be relative to that directory.\n\
3981dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003982 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003983
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003984PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003985"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003986Remove a file (same as unlink()).\n\
3987\n\
3988If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3989 and path should be relative; path will then be relative to that directory.\n\
3990dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003991 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003992
Barry Warsaw53699e91996-12-10 23:23:01 +00003993static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003994posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003995{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003996 path_t path;
3997 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003998 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999 int result;
4000 PyObject *return_value = NULL;
4001
4002 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004003 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004004 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004005 path_converter, &path,
4006#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004007 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004008#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004009 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004010#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004011 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004012 return NULL;
4013
4014 Py_BEGIN_ALLOW_THREADS
4015#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004016 if (path.wide)
4017 result = Py_DeleteFileW(path.wide);
4018 else
4019 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004020 result = !result; /* Windows, success=1, UNIX, success=0 */
4021#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004022#ifdef HAVE_UNLINKAT
4023 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004024 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004025 else
4026#endif /* HAVE_UNLINKAT */
4027 result = unlink(path.narrow);
4028#endif
4029 Py_END_ALLOW_THREADS
4030
4031 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004032 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004033 goto exit;
4034 }
4035
4036 return_value = Py_None;
4037 Py_INCREF(Py_None);
4038
4039exit:
4040 path_cleanup(&path);
4041 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004042}
4043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004044
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004045PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004046"uname() -> uname_result\n\n\
4047Return an object identifying the current operating system.\n\
4048The object behaves like a named tuple with the following fields:\n\
4049 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004050
Larry Hastings605a62d2012-06-24 04:33:36 -07004051static PyStructSequence_Field uname_result_fields[] = {
4052 {"sysname", "operating system name"},
4053 {"nodename", "name of machine on network (implementation-defined)"},
4054 {"release", "operating system release"},
4055 {"version", "operating system version"},
4056 {"machine", "hardware identifier"},
4057 {NULL}
4058};
4059
4060PyDoc_STRVAR(uname_result__doc__,
4061"uname_result: Result from os.uname().\n\n\
4062This object may be accessed either as a tuple of\n\
4063 (sysname, nodename, release, version, machine),\n\
4064or via the attributes sysname, nodename, release, version, and machine.\n\
4065\n\
4066See os.uname for more information.");
4067
4068static PyStructSequence_Desc uname_result_desc = {
4069 "uname_result", /* name */
4070 uname_result__doc__, /* doc */
4071 uname_result_fields,
4072 5
4073};
4074
4075static PyTypeObject UnameResultType;
4076
4077
4078#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004079static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004080posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004081{
Victor Stinner8c62be82010-05-06 00:08:46 +00004082 struct utsname u;
4083 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004084 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004085
Victor Stinner8c62be82010-05-06 00:08:46 +00004086 Py_BEGIN_ALLOW_THREADS
4087 res = uname(&u);
4088 Py_END_ALLOW_THREADS
4089 if (res < 0)
4090 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004091
4092 value = PyStructSequence_New(&UnameResultType);
4093 if (value == NULL)
4094 return NULL;
4095
4096#define SET(i, field) \
4097 { \
4098 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4099 if (!o) { \
4100 Py_DECREF(value); \
4101 return NULL; \
4102 } \
4103 PyStructSequence_SET_ITEM(value, i, o); \
4104 } \
4105
4106 SET(0, u.sysname);
4107 SET(1, u.nodename);
4108 SET(2, u.release);
4109 SET(3, u.version);
4110 SET(4, u.machine);
4111
4112#undef SET
4113
4114 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004115}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004116#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004117
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004118
Larry Hastings9cf065c2012-06-22 16:30:09 -07004119PyDoc_STRVAR(posix_utime__doc__,
4120"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4121Set the access and modified time of path.\n\
4122\n\
4123path may always be specified as a string.\n\
4124On some platforms, path may also be specified as an open file descriptor.\n\
4125 If this functionality is unavailable, using it raises an exception.\n\
4126\n\
4127If times is not None, it must be a tuple (atime, mtime);\n\
4128 atime and mtime should be expressed as float seconds since the epoch.\n\
4129If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4130 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4131 since the epoch.\n\
4132If both times and ns are None, utime uses the current time.\n\
4133Specifying tuples for both times and ns is an error.\n\
4134\n\
4135If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4136 and path should be relative; path will then be relative to that directory.\n\
4137If follow_symlinks is False, and the last element of the path is a symbolic\n\
4138 link, utime will modify the symbolic link itself instead of the file the\n\
4139 link points to.\n\
4140It is an error to use dir_fd or follow_symlinks when specifying path\n\
4141 as an open file descriptor.\n\
4142dir_fd and follow_symlinks may not be available on your platform.\n\
4143 If they are unavailable, using them will raise a NotImplementedError.");
4144
4145typedef struct {
4146 int now;
4147 time_t atime_s;
4148 long atime_ns;
4149 time_t mtime_s;
4150 long mtime_ns;
4151} utime_t;
4152
4153/*
4154 * these macros assume that "utime" is a pointer to a utime_t
4155 * they also intentionally leak the declaration of a pointer named "time"
4156 */
4157#define UTIME_TO_TIMESPEC \
4158 struct timespec ts[2]; \
4159 struct timespec *time; \
4160 if (utime->now) \
4161 time = NULL; \
4162 else { \
4163 ts[0].tv_sec = utime->atime_s; \
4164 ts[0].tv_nsec = utime->atime_ns; \
4165 ts[1].tv_sec = utime->mtime_s; \
4166 ts[1].tv_nsec = utime->mtime_ns; \
4167 time = ts; \
4168 } \
4169
4170#define UTIME_TO_TIMEVAL \
4171 struct timeval tv[2]; \
4172 struct timeval *time; \
4173 if (utime->now) \
4174 time = NULL; \
4175 else { \
4176 tv[0].tv_sec = utime->atime_s; \
4177 tv[0].tv_usec = utime->atime_ns / 1000; \
4178 tv[1].tv_sec = utime->mtime_s; \
4179 tv[1].tv_usec = utime->mtime_ns / 1000; \
4180 time = tv; \
4181 } \
4182
4183#define UTIME_TO_UTIMBUF \
4184 struct utimbuf u[2]; \
4185 struct utimbuf *time; \
4186 if (utime->now) \
4187 time = NULL; \
4188 else { \
4189 u.actime = utime->atime_s; \
4190 u.modtime = utime->mtime_s; \
4191 time = u; \
4192 }
4193
4194#define UTIME_TO_TIME_T \
4195 time_t timet[2]; \
4196 struct timet time; \
4197 if (utime->now) \
4198 time = NULL; \
4199 else { \
4200 timet[0] = utime->atime_s; \
4201 timet[1] = utime->mtime_s; \
4202 time = &timet; \
4203 } \
4204
4205
4206#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4207
4208#if UTIME_HAVE_DIR_FD
4209
4210static int
4211utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4212{
4213#ifdef HAVE_UTIMENSAT
4214 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4215 UTIME_TO_TIMESPEC;
4216 return utimensat(dir_fd, path, time, flags);
4217#elif defined(HAVE_FUTIMESAT)
4218 UTIME_TO_TIMEVAL;
4219 /*
4220 * follow_symlinks will never be false here;
4221 * we only allow !follow_symlinks and dir_fd together
4222 * if we have utimensat()
4223 */
4224 assert(follow_symlinks);
4225 return futimesat(dir_fd, path, time);
4226#endif
4227}
4228
4229#endif
4230
4231#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4232
4233#if UTIME_HAVE_FD
4234
4235static int
4236utime_fd(utime_t *utime, int fd)
4237{
4238#ifdef HAVE_FUTIMENS
4239 UTIME_TO_TIMESPEC;
4240 return futimens(fd, time);
4241#else
4242 UTIME_TO_TIMEVAL;
4243 return futimes(fd, time);
4244#endif
4245}
4246
4247#endif
4248
4249
4250#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4251 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4252
4253#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4254
4255static int
4256utime_nofollow_symlinks(utime_t *utime, char *path)
4257{
4258#ifdef HAVE_UTIMENSAT
4259 UTIME_TO_TIMESPEC;
4260 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4261#else
4262 UTIME_TO_TIMEVAL;
4263 return lutimes(path, time);
4264#endif
4265}
4266
4267#endif
4268
4269#ifndef MS_WINDOWS
4270
4271static int
4272utime_default(utime_t *utime, char *path)
4273{
4274#ifdef HAVE_UTIMENSAT
4275 UTIME_TO_TIMESPEC;
4276 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4277#elif defined(HAVE_UTIMES)
4278 UTIME_TO_TIMEVAL;
4279 return utimes(path, time);
4280#elif defined(HAVE_UTIME_H)
4281 UTIME_TO_UTIMBUF;
4282 return utime(path, time);
4283#else
4284 UTIME_TO_TIME_T;
4285 return utime(path, time);
4286#endif
4287}
4288
4289#endif
4290
Larry Hastings76ad59b2012-05-03 00:30:07 -07004291static int
4292split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4293{
4294 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004295 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004296 divmod = PyNumber_Divmod(py_long, billion);
4297 if (!divmod)
4298 goto exit;
4299 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4300 if ((*s == -1) && PyErr_Occurred())
4301 goto exit;
4302 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004303 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004304 goto exit;
4305
4306 result = 1;
4307exit:
4308 Py_XDECREF(divmod);
4309 return result;
4310}
4311
Larry Hastings9cf065c2012-06-22 16:30:09 -07004312static PyObject *
4313posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004314{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004315 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004316 PyObject *times = NULL;
4317 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004318 int dir_fd = DEFAULT_DIR_FD;
4319 int follow_symlinks = 1;
4320 char *keywords[] = {"path", "times", "ns", "dir_fd",
4321 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004322
Larry Hastings9cf065c2012-06-22 16:30:09 -07004323 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004324
Larry Hastings9cf065c2012-06-22 16:30:09 -07004325#ifdef MS_WINDOWS
4326 HANDLE hFile;
4327 FILETIME atime, mtime;
4328#else
4329 int result;
4330#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004331
Larry Hastings9cf065c2012-06-22 16:30:09 -07004332 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004333
Larry Hastings9cf065c2012-06-22 16:30:09 -07004334 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004335 path.function_name = "utime";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004336#if UTIME_HAVE_FD
4337 path.allow_fd = 1;
4338#endif
4339 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4340 "O&|O$OO&p:utime", keywords,
4341 path_converter, &path,
4342 &times, &ns,
4343#if UTIME_HAVE_DIR_FD
4344 dir_fd_converter, &dir_fd,
4345#else
4346 dir_fd_unavailable, &dir_fd,
4347#endif
4348 &follow_symlinks
4349 ))
4350 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004351
Larry Hastings9cf065c2012-06-22 16:30:09 -07004352 if (times && (times != Py_None) && ns) {
4353 PyErr_SetString(PyExc_ValueError,
4354 "utime: you may specify either 'times'"
4355 " or 'ns' but not both");
4356 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004357 }
4358
4359 if (times && (times != Py_None)) {
4360 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004361 PyErr_SetString(PyExc_TypeError,
4362 "utime: 'times' must be either"
4363 " a tuple of two ints or None");
4364 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004365 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004366 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004367 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004368 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004369 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004370 &utime.mtime_s, &utime.mtime_ns) == -1) {
4371 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004372 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004373 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004374 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004375 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004376 PyErr_SetString(PyExc_TypeError,
4377 "utime: 'ns' must be a tuple of two ints");
4378 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004379 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004380 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004381 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004383 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384 &utime.mtime_s, &utime.mtime_ns)) {
4385 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004386 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004387 }
4388 else {
4389 /* times and ns are both None/unspecified. use "now". */
4390 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004391 }
4392
Larry Hastings9cf065c2012-06-22 16:30:09 -07004393#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4394 if (follow_symlinks_specified("utime", follow_symlinks))
4395 goto exit;
4396#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004397
Larry Hastings9cf065c2012-06-22 16:30:09 -07004398 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4399 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4400 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4401 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004402
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403#if !defined(HAVE_UTIMENSAT)
4404 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004405 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004406 "utime: cannot use dir_fd and follow_symlinks "
4407 "together on this platform");
4408 goto exit;
4409 }
4410#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004411
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004412#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004413 Py_BEGIN_ALLOW_THREADS
4414 if (path.wide)
4415 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004416 NULL, OPEN_EXISTING,
4417 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004418 else
4419 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004420 NULL, OPEN_EXISTING,
4421 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004422 Py_END_ALLOW_THREADS
4423 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004424 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004425 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004426 }
4427
Larry Hastings9cf065c2012-06-22 16:30:09 -07004428 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004429 SYSTEMTIME now;
4430 GetSystemTime(&now);
4431 if (!SystemTimeToFileTime(&now, &mtime) ||
4432 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004433 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004434 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004435 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004437 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004438 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4439 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004440 }
4441 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4442 /* Avoid putting the file name into the error here,
4443 as that may confuse the user into believing that
4444 something is wrong with the file, when it also
4445 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004446 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004447 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004448 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004449#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004451
Larry Hastings9cf065c2012-06-22 16:30:09 -07004452#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4453 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4454 result = utime_nofollow_symlinks(&utime, path.narrow);
4455 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004456#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004457
4458#if UTIME_HAVE_DIR_FD
4459 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4460 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4461 else
4462#endif
4463
4464#if UTIME_HAVE_FD
4465 if (path.fd != -1)
4466 result = utime_fd(&utime, path.fd);
4467 else
4468#endif
4469
4470 result = utime_default(&utime, path.narrow);
4471
4472 Py_END_ALLOW_THREADS
4473
4474 if (result < 0) {
4475 /* see previous comment about not putting filename in error here */
4476 return_value = posix_error();
4477 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004478 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004479
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004480#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004481
4482 Py_INCREF(Py_None);
4483 return_value = Py_None;
4484
4485exit:
4486 path_cleanup(&path);
4487#ifdef MS_WINDOWS
4488 if (hFile != INVALID_HANDLE_VALUE)
4489 CloseHandle(hFile);
4490#endif
4491 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004492}
4493
Guido van Rossum3b066191991-06-04 19:40:25 +00004494/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004495
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004496PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004497"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004498Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004499
Barry Warsaw53699e91996-12-10 23:23:01 +00004500static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004501posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004502{
Victor Stinner8c62be82010-05-06 00:08:46 +00004503 int sts;
4504 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4505 return NULL;
4506 _exit(sts);
4507 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004508}
4509
Martin v. Löwis114619e2002-10-07 06:44:21 +00004510#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4511static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004512free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004513{
Victor Stinner8c62be82010-05-06 00:08:46 +00004514 Py_ssize_t i;
4515 for (i = 0; i < count; i++)
4516 PyMem_Free(array[i]);
4517 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004518}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004519
Antoine Pitrou69f71142009-05-24 21:25:49 +00004520static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004521int fsconvert_strdup(PyObject *o, char**out)
4522{
Victor Stinner8c62be82010-05-06 00:08:46 +00004523 PyObject *bytes;
4524 Py_ssize_t size;
4525 if (!PyUnicode_FSConverter(o, &bytes))
4526 return 0;
4527 size = PyBytes_GET_SIZE(bytes);
4528 *out = PyMem_Malloc(size+1);
4529 if (!*out)
4530 return 0;
4531 memcpy(*out, PyBytes_AsString(bytes), size+1);
4532 Py_DECREF(bytes);
4533 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004534}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004535#endif
4536
Ross Lagerwall7807c352011-03-17 20:20:30 +02004537#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004538static char**
4539parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4540{
Victor Stinner8c62be82010-05-06 00:08:46 +00004541 char **envlist;
4542 Py_ssize_t i, pos, envc;
4543 PyObject *keys=NULL, *vals=NULL;
4544 PyObject *key, *val, *key2, *val2;
4545 char *p, *k, *v;
4546 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004547
Victor Stinner8c62be82010-05-06 00:08:46 +00004548 i = PyMapping_Size(env);
4549 if (i < 0)
4550 return NULL;
4551 envlist = PyMem_NEW(char *, i + 1);
4552 if (envlist == NULL) {
4553 PyErr_NoMemory();
4554 return NULL;
4555 }
4556 envc = 0;
4557 keys = PyMapping_Keys(env);
4558 vals = PyMapping_Values(env);
4559 if (!keys || !vals)
4560 goto error;
4561 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4562 PyErr_Format(PyExc_TypeError,
4563 "env.keys() or env.values() is not a list");
4564 goto error;
4565 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004566
Victor Stinner8c62be82010-05-06 00:08:46 +00004567 for (pos = 0; pos < i; pos++) {
4568 key = PyList_GetItem(keys, pos);
4569 val = PyList_GetItem(vals, pos);
4570 if (!key || !val)
4571 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004572
Victor Stinner8c62be82010-05-06 00:08:46 +00004573 if (PyUnicode_FSConverter(key, &key2) == 0)
4574 goto error;
4575 if (PyUnicode_FSConverter(val, &val2) == 0) {
4576 Py_DECREF(key2);
4577 goto error;
4578 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004579
Victor Stinner8c62be82010-05-06 00:08:46 +00004580 k = PyBytes_AsString(key2);
4581 v = PyBytes_AsString(val2);
4582 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004583
Victor Stinner8c62be82010-05-06 00:08:46 +00004584 p = PyMem_NEW(char, len);
4585 if (p == NULL) {
4586 PyErr_NoMemory();
4587 Py_DECREF(key2);
4588 Py_DECREF(val2);
4589 goto error;
4590 }
4591 PyOS_snprintf(p, len, "%s=%s", k, v);
4592 envlist[envc++] = p;
4593 Py_DECREF(key2);
4594 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004595 }
4596 Py_DECREF(vals);
4597 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004598
Victor Stinner8c62be82010-05-06 00:08:46 +00004599 envlist[envc] = 0;
4600 *envc_ptr = envc;
4601 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004602
4603error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004604 Py_XDECREF(keys);
4605 Py_XDECREF(vals);
4606 while (--envc >= 0)
4607 PyMem_DEL(envlist[envc]);
4608 PyMem_DEL(envlist);
4609 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004610}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004611
Ross Lagerwall7807c352011-03-17 20:20:30 +02004612static char**
4613parse_arglist(PyObject* argv, Py_ssize_t *argc)
4614{
4615 int i;
4616 char **argvlist = PyMem_NEW(char *, *argc+1);
4617 if (argvlist == NULL) {
4618 PyErr_NoMemory();
4619 return NULL;
4620 }
4621 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004622 PyObject* item = PySequence_ITEM(argv, i);
4623 if (item == NULL)
4624 goto fail;
4625 if (!fsconvert_strdup(item, &argvlist[i])) {
4626 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004627 goto fail;
4628 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004629 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004630 }
4631 argvlist[*argc] = NULL;
4632 return argvlist;
4633fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004634 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004635 free_string_array(argvlist, *argc);
4636 return NULL;
4637}
4638#endif
4639
4640#ifdef HAVE_EXECV
4641PyDoc_STRVAR(posix_execv__doc__,
4642"execv(path, args)\n\n\
4643Execute an executable path with arguments, replacing current process.\n\
4644\n\
4645 path: path of executable file\n\
4646 args: tuple or list of strings");
4647
4648static PyObject *
4649posix_execv(PyObject *self, PyObject *args)
4650{
4651 PyObject *opath;
4652 char *path;
4653 PyObject *argv;
4654 char **argvlist;
4655 Py_ssize_t argc;
4656
4657 /* execv has two arguments: (path, argv), where
4658 argv is a list or tuple of strings. */
4659
4660 if (!PyArg_ParseTuple(args, "O&O:execv",
4661 PyUnicode_FSConverter,
4662 &opath, &argv))
4663 return NULL;
4664 path = PyBytes_AsString(opath);
4665 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4666 PyErr_SetString(PyExc_TypeError,
4667 "execv() arg 2 must be a tuple or list");
4668 Py_DECREF(opath);
4669 return NULL;
4670 }
4671 argc = PySequence_Size(argv);
4672 if (argc < 1) {
4673 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4674 Py_DECREF(opath);
4675 return NULL;
4676 }
4677
4678 argvlist = parse_arglist(argv, &argc);
4679 if (argvlist == NULL) {
4680 Py_DECREF(opath);
4681 return NULL;
4682 }
4683
4684 execv(path, argvlist);
4685
4686 /* If we get here it's definitely an error */
4687
4688 free_string_array(argvlist, argc);
4689 Py_DECREF(opath);
4690 return posix_error();
4691}
4692
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004693PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004694"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004695Execute a path with arguments and environment, replacing current process.\n\
4696\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004697 path: path of executable file\n\
4698 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004699 env: dictionary of strings mapping to strings\n\
4700\n\
4701On some platforms, you may specify an open file descriptor for path;\n\
4702 execve will execute the program the file descriptor is open to.\n\
4703 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004704
Barry Warsaw53699e91996-12-10 23:23:01 +00004705static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004707{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004708 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004709 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004710 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004711 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004712 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004714
Victor Stinner8c62be82010-05-06 00:08:46 +00004715 /* execve has three arguments: (path, argv, env), where
4716 argv is a list or tuple of strings and env is a dictionary
4717 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004718
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004720 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721#ifdef HAVE_FEXECVE
4722 path.allow_fd = 1;
4723#endif
4724 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4725 path_converter, &path,
4726 &argv, &env
4727 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004728 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729
Ross Lagerwall7807c352011-03-17 20:20:30 +02004730 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004731 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732 "execve: argv must be a tuple or list");
4733 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004734 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004735 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004736 if (!PyMapping_Check(env)) {
4737 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 "execve: environment must be a mapping object");
4739 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004740 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004741
Ross Lagerwall7807c352011-03-17 20:20:30 +02004742 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004743 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004745 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004746
Victor Stinner8c62be82010-05-06 00:08:46 +00004747 envlist = parse_envlist(env, &envc);
4748 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004749 goto fail;
4750
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751#ifdef HAVE_FEXECVE
4752 if (path.fd > -1)
4753 fexecve(path.fd, argvlist, envlist);
4754 else
4755#endif
4756 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004757
4758 /* If we get here it's definitely an error */
4759
Victor Stinner292c8352012-10-30 02:17:38 +01004760 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004761
4762 while (--envc >= 0)
4763 PyMem_DEL(envlist[envc]);
4764 PyMem_DEL(envlist);
4765 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004766 if (argvlist)
4767 free_string_array(argvlist, argc);
4768 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004769 return NULL;
4770}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004771#endif /* HAVE_EXECV */
4772
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004773
Guido van Rossuma1065681999-01-25 23:20:23 +00004774#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004775PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004776"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004777Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004778\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 mode: mode of process creation\n\
4780 path: path of executable file\n\
4781 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004782
4783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004784posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004785{
Victor Stinner8c62be82010-05-06 00:08:46 +00004786 PyObject *opath;
4787 char *path;
4788 PyObject *argv;
4789 char **argvlist;
4790 int mode, i;
4791 Py_ssize_t argc;
4792 Py_intptr_t spawnval;
4793 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004794
Victor Stinner8c62be82010-05-06 00:08:46 +00004795 /* spawnv has three arguments: (mode, path, argv), where
4796 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004797
Victor Stinner8c62be82010-05-06 00:08:46 +00004798 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4799 PyUnicode_FSConverter,
4800 &opath, &argv))
4801 return NULL;
4802 path = PyBytes_AsString(opath);
4803 if (PyList_Check(argv)) {
4804 argc = PyList_Size(argv);
4805 getitem = PyList_GetItem;
4806 }
4807 else if (PyTuple_Check(argv)) {
4808 argc = PyTuple_Size(argv);
4809 getitem = PyTuple_GetItem;
4810 }
4811 else {
4812 PyErr_SetString(PyExc_TypeError,
4813 "spawnv() arg 2 must be a tuple or list");
4814 Py_DECREF(opath);
4815 return NULL;
4816 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004817
Victor Stinner8c62be82010-05-06 00:08:46 +00004818 argvlist = PyMem_NEW(char *, argc+1);
4819 if (argvlist == NULL) {
4820 Py_DECREF(opath);
4821 return PyErr_NoMemory();
4822 }
4823 for (i = 0; i < argc; i++) {
4824 if (!fsconvert_strdup((*getitem)(argv, i),
4825 &argvlist[i])) {
4826 free_string_array(argvlist, i);
4827 PyErr_SetString(
4828 PyExc_TypeError,
4829 "spawnv() arg 2 must contain only strings");
4830 Py_DECREF(opath);
4831 return NULL;
4832 }
4833 }
4834 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004835
Victor Stinner8c62be82010-05-06 00:08:46 +00004836 if (mode == _OLD_P_OVERLAY)
4837 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004838
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 Py_BEGIN_ALLOW_THREADS
4840 spawnval = _spawnv(mode, path, argvlist);
4841 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00004842
Victor Stinner8c62be82010-05-06 00:08:46 +00004843 free_string_array(argvlist, argc);
4844 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004845
Victor Stinner8c62be82010-05-06 00:08:46 +00004846 if (spawnval == -1)
4847 return posix_error();
4848 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004849#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004850 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004851#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004852 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004853#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004854}
4855
4856
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004857PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004858"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004859Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004860\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004861 mode: mode of process creation\n\
4862 path: path of executable file\n\
4863 args: tuple or list of arguments\n\
4864 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004865
4866static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004867posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004868{
Victor Stinner8c62be82010-05-06 00:08:46 +00004869 PyObject *opath;
4870 char *path;
4871 PyObject *argv, *env;
4872 char **argvlist;
4873 char **envlist;
4874 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004875 int mode;
4876 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004877 Py_intptr_t spawnval;
4878 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4879 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004880
Victor Stinner8c62be82010-05-06 00:08:46 +00004881 /* spawnve has four arguments: (mode, path, argv, env), where
4882 argv is a list or tuple of strings and env is a dictionary
4883 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004884
Victor Stinner8c62be82010-05-06 00:08:46 +00004885 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4886 PyUnicode_FSConverter,
4887 &opath, &argv, &env))
4888 return NULL;
4889 path = PyBytes_AsString(opath);
4890 if (PyList_Check(argv)) {
4891 argc = PyList_Size(argv);
4892 getitem = PyList_GetItem;
4893 }
4894 else if (PyTuple_Check(argv)) {
4895 argc = PyTuple_Size(argv);
4896 getitem = PyTuple_GetItem;
4897 }
4898 else {
4899 PyErr_SetString(PyExc_TypeError,
4900 "spawnve() arg 2 must be a tuple or list");
4901 goto fail_0;
4902 }
4903 if (!PyMapping_Check(env)) {
4904 PyErr_SetString(PyExc_TypeError,
4905 "spawnve() arg 3 must be a mapping object");
4906 goto fail_0;
4907 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004908
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 argvlist = PyMem_NEW(char *, argc+1);
4910 if (argvlist == NULL) {
4911 PyErr_NoMemory();
4912 goto fail_0;
4913 }
4914 for (i = 0; i < argc; i++) {
4915 if (!fsconvert_strdup((*getitem)(argv, i),
4916 &argvlist[i]))
4917 {
4918 lastarg = i;
4919 goto fail_1;
4920 }
4921 }
4922 lastarg = argc;
4923 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004924
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 envlist = parse_envlist(env, &envc);
4926 if (envlist == NULL)
4927 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004928
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 if (mode == _OLD_P_OVERLAY)
4930 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004931
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 Py_BEGIN_ALLOW_THREADS
4933 spawnval = _spawnve(mode, path, argvlist, envlist);
4934 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00004935
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 if (spawnval == -1)
4937 (void) posix_error();
4938 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004939#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004941#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004943#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004944
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 while (--envc >= 0)
4946 PyMem_DEL(envlist[envc]);
4947 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004948 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004949 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004950 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004951 Py_DECREF(opath);
4952 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004953}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004954
Guido van Rossuma1065681999-01-25 23:20:23 +00004955#endif /* HAVE_SPAWNV */
4956
4957
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004958#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004959PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004960"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004961Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4962\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004963Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004964
4965static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004966posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004967{
Victor Stinner8c62be82010-05-06 00:08:46 +00004968 pid_t pid;
4969 int result = 0;
4970 _PyImport_AcquireLock();
4971 pid = fork1();
4972 if (pid == 0) {
4973 /* child: this clobbers and resets the import lock. */
4974 PyOS_AfterFork();
4975 } else {
4976 /* parent: release the import lock. */
4977 result = _PyImport_ReleaseLock();
4978 }
4979 if (pid == -1)
4980 return posix_error();
4981 if (result < 0) {
4982 /* Don't clobber the OSError if the fork failed. */
4983 PyErr_SetString(PyExc_RuntimeError,
4984 "not holding the import lock");
4985 return NULL;
4986 }
4987 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004988}
4989#endif
4990
4991
Guido van Rossumad0ee831995-03-01 10:34:45 +00004992#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004993PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004994"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004995Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004996Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004997
Barry Warsaw53699e91996-12-10 23:23:01 +00004998static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004999posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005000{
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 pid_t pid;
5002 int result = 0;
5003 _PyImport_AcquireLock();
5004 pid = fork();
5005 if (pid == 0) {
5006 /* child: this clobbers and resets the import lock. */
5007 PyOS_AfterFork();
5008 } else {
5009 /* parent: release the import lock. */
5010 result = _PyImport_ReleaseLock();
5011 }
5012 if (pid == -1)
5013 return posix_error();
5014 if (result < 0) {
5015 /* Don't clobber the OSError if the fork failed. */
5016 PyErr_SetString(PyExc_RuntimeError,
5017 "not holding the import lock");
5018 return NULL;
5019 }
5020 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005021}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005022#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005023
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005024#ifdef HAVE_SCHED_H
5025
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005026#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5027
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005028PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5029"sched_get_priority_max(policy)\n\n\
5030Get the maximum scheduling priority for *policy*.");
5031
5032static PyObject *
5033posix_sched_get_priority_max(PyObject *self, PyObject *args)
5034{
5035 int policy, max;
5036
5037 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5038 return NULL;
5039 max = sched_get_priority_max(policy);
5040 if (max < 0)
5041 return posix_error();
5042 return PyLong_FromLong(max);
5043}
5044
5045PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5046"sched_get_priority_min(policy)\n\n\
5047Get the minimum scheduling priority for *policy*.");
5048
5049static PyObject *
5050posix_sched_get_priority_min(PyObject *self, PyObject *args)
5051{
5052 int policy, min;
5053
5054 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5055 return NULL;
5056 min = sched_get_priority_min(policy);
5057 if (min < 0)
5058 return posix_error();
5059 return PyLong_FromLong(min);
5060}
5061
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005062#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5063
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005064#ifdef HAVE_SCHED_SETSCHEDULER
5065
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005066PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5067"sched_getscheduler(pid)\n\n\
5068Get the scheduling policy for the process with a PID of *pid*.\n\
5069Passing a PID of 0 returns the scheduling policy for the calling process.");
5070
5071static PyObject *
5072posix_sched_getscheduler(PyObject *self, PyObject *args)
5073{
5074 pid_t pid;
5075 int policy;
5076
5077 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5078 return NULL;
5079 policy = sched_getscheduler(pid);
5080 if (policy < 0)
5081 return posix_error();
5082 return PyLong_FromLong(policy);
5083}
5084
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005085#endif
5086
5087#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5088
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005089static PyObject *
5090sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5091{
5092 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005093 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005094
5095 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5096 return NULL;
5097 res = PyStructSequence_New(type);
5098 if (!res)
5099 return NULL;
5100 Py_INCREF(priority);
5101 PyStructSequence_SET_ITEM(res, 0, priority);
5102 return res;
5103}
5104
5105PyDoc_STRVAR(sched_param__doc__,
5106"sched_param(sched_priority): A scheduling parameter.\n\n\
5107Current has only one field: sched_priority");
5108
5109static PyStructSequence_Field sched_param_fields[] = {
5110 {"sched_priority", "the scheduling priority"},
5111 {0}
5112};
5113
5114static PyStructSequence_Desc sched_param_desc = {
5115 "sched_param", /* name */
5116 sched_param__doc__, /* doc */
5117 sched_param_fields,
5118 1
5119};
5120
5121static int
5122convert_sched_param(PyObject *param, struct sched_param *res)
5123{
5124 long priority;
5125
5126 if (Py_TYPE(param) != &SchedParamType) {
5127 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5128 return 0;
5129 }
5130 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5131 if (priority == -1 && PyErr_Occurred())
5132 return 0;
5133 if (priority > INT_MAX || priority < INT_MIN) {
5134 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5135 return 0;
5136 }
5137 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5138 return 1;
5139}
5140
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005141#endif
5142
5143#ifdef HAVE_SCHED_SETSCHEDULER
5144
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005145PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5146"sched_setscheduler(pid, policy, param)\n\n\
5147Set the scheduling policy, *policy*, for *pid*.\n\
5148If *pid* is 0, the calling process is changed.\n\
5149*param* is an instance of sched_param.");
5150
5151static PyObject *
5152posix_sched_setscheduler(PyObject *self, PyObject *args)
5153{
5154 pid_t pid;
5155 int policy;
5156 struct sched_param param;
5157
5158 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5159 &pid, &policy, &convert_sched_param, &param))
5160 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005161
5162 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005163 ** sched_setscheduler() returns 0 in Linux, but the previous
5164 ** scheduling policy under Solaris/Illumos, and others.
5165 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005166 */
5167 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005168 return posix_error();
5169 Py_RETURN_NONE;
5170}
5171
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005172#endif
5173
5174#ifdef HAVE_SCHED_SETPARAM
5175
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005176PyDoc_STRVAR(posix_sched_getparam__doc__,
5177"sched_getparam(pid) -> sched_param\n\n\
5178Returns scheduling parameters for the process with *pid* as an instance of the\n\
5179sched_param class. A PID of 0 means the calling process.");
5180
5181static PyObject *
5182posix_sched_getparam(PyObject *self, PyObject *args)
5183{
5184 pid_t pid;
5185 struct sched_param param;
5186 PyObject *res, *priority;
5187
5188 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5189 return NULL;
5190 if (sched_getparam(pid, &param))
5191 return posix_error();
5192 res = PyStructSequence_New(&SchedParamType);
5193 if (!res)
5194 return NULL;
5195 priority = PyLong_FromLong(param.sched_priority);
5196 if (!priority) {
5197 Py_DECREF(res);
5198 return NULL;
5199 }
5200 PyStructSequence_SET_ITEM(res, 0, priority);
5201 return res;
5202}
5203
5204PyDoc_STRVAR(posix_sched_setparam__doc__,
5205"sched_setparam(pid, param)\n\n\
5206Set scheduling parameters for a process with PID *pid*.\n\
5207A PID of 0 means the calling process.");
5208
5209static PyObject *
5210posix_sched_setparam(PyObject *self, PyObject *args)
5211{
5212 pid_t pid;
5213 struct sched_param param;
5214
5215 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5216 &pid, &convert_sched_param, &param))
5217 return NULL;
5218 if (sched_setparam(pid, &param))
5219 return posix_error();
5220 Py_RETURN_NONE;
5221}
5222
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005223#endif
5224
5225#ifdef HAVE_SCHED_RR_GET_INTERVAL
5226
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005227PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5228"sched_rr_get_interval(pid) -> float\n\n\
5229Return the round-robin quantum for the process with PID *pid* in seconds.");
5230
5231static PyObject *
5232posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5233{
5234 pid_t pid;
5235 struct timespec interval;
5236
5237 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5238 return NULL;
5239 if (sched_rr_get_interval(pid, &interval))
5240 return posix_error();
5241 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5242}
5243
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005244#endif
5245
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005246PyDoc_STRVAR(posix_sched_yield__doc__,
5247"sched_yield()\n\n\
5248Voluntarily relinquish the CPU.");
5249
5250static PyObject *
5251posix_sched_yield(PyObject *self, PyObject *noargs)
5252{
5253 if (sched_yield())
5254 return posix_error();
5255 Py_RETURN_NONE;
5256}
5257
Benjamin Peterson2740af82011-08-02 17:41:34 -05005258#ifdef HAVE_SCHED_SETAFFINITY
5259
Antoine Pitrou84869872012-08-04 16:16:35 +02005260/* The minimum number of CPUs allocated in a cpu_set_t */
5261static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005262
5263PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5264"sched_setaffinity(pid, cpu_set)\n\n\
5265Set the affinity of the process with PID *pid* to *cpu_set*.");
5266
5267static PyObject *
5268posix_sched_setaffinity(PyObject *self, PyObject *args)
5269{
5270 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005271 int ncpus;
5272 size_t setsize;
5273 cpu_set_t *mask = NULL;
5274 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005275
Antoine Pitrou84869872012-08-04 16:16:35 +02005276 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5277 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005278 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005279
5280 iterator = PyObject_GetIter(iterable);
5281 if (iterator == NULL)
5282 return NULL;
5283
5284 ncpus = NCPUS_START;
5285 setsize = CPU_ALLOC_SIZE(ncpus);
5286 mask = CPU_ALLOC(ncpus);
5287 if (mask == NULL) {
5288 PyErr_NoMemory();
5289 goto error;
5290 }
5291 CPU_ZERO_S(setsize, mask);
5292
5293 while ((item = PyIter_Next(iterator))) {
5294 long cpu;
5295 if (!PyLong_Check(item)) {
5296 PyErr_Format(PyExc_TypeError,
5297 "expected an iterator of ints, "
5298 "but iterator yielded %R",
5299 Py_TYPE(item));
5300 Py_DECREF(item);
5301 goto error;
5302 }
5303 cpu = PyLong_AsLong(item);
5304 Py_DECREF(item);
5305 if (cpu < 0) {
5306 if (!PyErr_Occurred())
5307 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5308 goto error;
5309 }
5310 if (cpu > INT_MAX - 1) {
5311 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5312 goto error;
5313 }
5314 if (cpu >= ncpus) {
5315 /* Grow CPU mask to fit the CPU number */
5316 int newncpus = ncpus;
5317 cpu_set_t *newmask;
5318 size_t newsetsize;
5319 while (newncpus <= cpu) {
5320 if (newncpus > INT_MAX / 2)
5321 newncpus = cpu + 1;
5322 else
5323 newncpus = newncpus * 2;
5324 }
5325 newmask = CPU_ALLOC(newncpus);
5326 if (newmask == NULL) {
5327 PyErr_NoMemory();
5328 goto error;
5329 }
5330 newsetsize = CPU_ALLOC_SIZE(newncpus);
5331 CPU_ZERO_S(newsetsize, newmask);
5332 memcpy(newmask, mask, setsize);
5333 CPU_FREE(mask);
5334 setsize = newsetsize;
5335 mask = newmask;
5336 ncpus = newncpus;
5337 }
5338 CPU_SET_S(cpu, setsize, mask);
5339 }
5340 Py_CLEAR(iterator);
5341
5342 if (sched_setaffinity(pid, setsize, mask)) {
5343 posix_error();
5344 goto error;
5345 }
5346 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005347 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005348
5349error:
5350 if (mask)
5351 CPU_FREE(mask);
5352 Py_XDECREF(iterator);
5353 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005354}
5355
5356PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5357"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5358Return the affinity of the process with PID *pid*.\n\
5359The returned cpu_set will be of size *ncpus*.");
5360
5361static PyObject *
5362posix_sched_getaffinity(PyObject *self, PyObject *args)
5363{
5364 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005365 int cpu, ncpus, count;
5366 size_t setsize;
5367 cpu_set_t *mask = NULL;
5368 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005369
Antoine Pitrou84869872012-08-04 16:16:35 +02005370 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5371 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005372 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005373
5374 ncpus = NCPUS_START;
5375 while (1) {
5376 setsize = CPU_ALLOC_SIZE(ncpus);
5377 mask = CPU_ALLOC(ncpus);
5378 if (mask == NULL)
5379 return PyErr_NoMemory();
5380 if (sched_getaffinity(pid, setsize, mask) == 0)
5381 break;
5382 CPU_FREE(mask);
5383 if (errno != EINVAL)
5384 return posix_error();
5385 if (ncpus > INT_MAX / 2) {
5386 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5387 "a large enough CPU set");
5388 return NULL;
5389 }
5390 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005391 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005392
5393 res = PySet_New(NULL);
5394 if (res == NULL)
5395 goto error;
5396 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5397 if (CPU_ISSET_S(cpu, setsize, mask)) {
5398 PyObject *cpu_num = PyLong_FromLong(cpu);
5399 --count;
5400 if (cpu_num == NULL)
5401 goto error;
5402 if (PySet_Add(res, cpu_num)) {
5403 Py_DECREF(cpu_num);
5404 goto error;
5405 }
5406 Py_DECREF(cpu_num);
5407 }
5408 }
5409 CPU_FREE(mask);
5410 return res;
5411
5412error:
5413 if (mask)
5414 CPU_FREE(mask);
5415 Py_XDECREF(res);
5416 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005417}
5418
Benjamin Peterson2740af82011-08-02 17:41:34 -05005419#endif /* HAVE_SCHED_SETAFFINITY */
5420
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005421#endif /* HAVE_SCHED_H */
5422
Neal Norwitzb59798b2003-03-21 01:43:31 +00005423/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005424/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5425#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005426#define DEV_PTY_FILE "/dev/ptc"
5427#define HAVE_DEV_PTMX
5428#else
5429#define DEV_PTY_FILE "/dev/ptmx"
5430#endif
5431
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005432#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005433#ifdef HAVE_PTY_H
5434#include <pty.h>
5435#else
5436#ifdef HAVE_LIBUTIL_H
5437#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005438#else
5439#ifdef HAVE_UTIL_H
5440#include <util.h>
5441#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005442#endif /* HAVE_LIBUTIL_H */
5443#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005444#ifdef HAVE_STROPTS_H
5445#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005446#endif
5447#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005448
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005449#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005450PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005451"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005452Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005453
5454static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005455posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005456{
Victor Stinner8c62be82010-05-06 00:08:46 +00005457 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005458#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005459 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005460#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005461#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005462 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005463#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005464 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005465#endif
5466#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005467
Thomas Wouters70c21a12000-07-14 14:28:33 +00005468#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005469 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5470 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005471#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005472 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5473 if (slave_name == NULL)
5474 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005475
Victor Stinner8c62be82010-05-06 00:08:46 +00005476 slave_fd = open(slave_name, O_RDWR);
5477 if (slave_fd < 0)
5478 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005479#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005480 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5481 if (master_fd < 0)
5482 return posix_error();
5483 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5484 /* change permission of slave */
5485 if (grantpt(master_fd) < 0) {
5486 PyOS_setsig(SIGCHLD, sig_saved);
5487 return posix_error();
5488 }
5489 /* unlock slave */
5490 if (unlockpt(master_fd) < 0) {
5491 PyOS_setsig(SIGCHLD, sig_saved);
5492 return posix_error();
5493 }
5494 PyOS_setsig(SIGCHLD, sig_saved);
5495 slave_name = ptsname(master_fd); /* get name of slave */
5496 if (slave_name == NULL)
5497 return posix_error();
5498 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5499 if (slave_fd < 0)
5500 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005501#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005502 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5503 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005504#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005505 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005506#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005507#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005508#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005509
Victor Stinner8c62be82010-05-06 00:08:46 +00005510 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005511
Fred Drake8cef4cf2000-06-28 16:40:38 +00005512}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005513#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005514
5515#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005516PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005517"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005518Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5519Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005520To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005521
5522static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005523posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005524{
Victor Stinner8c62be82010-05-06 00:08:46 +00005525 int master_fd = -1, result = 0;
5526 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005527
Victor Stinner8c62be82010-05-06 00:08:46 +00005528 _PyImport_AcquireLock();
5529 pid = forkpty(&master_fd, NULL, NULL, NULL);
5530 if (pid == 0) {
5531 /* child: this clobbers and resets the import lock. */
5532 PyOS_AfterFork();
5533 } else {
5534 /* parent: release the import lock. */
5535 result = _PyImport_ReleaseLock();
5536 }
5537 if (pid == -1)
5538 return posix_error();
5539 if (result < 0) {
5540 /* Don't clobber the OSError if the fork failed. */
5541 PyErr_SetString(PyExc_RuntimeError,
5542 "not holding the import lock");
5543 return NULL;
5544 }
5545 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005546}
5547#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005548
Ross Lagerwall7807c352011-03-17 20:20:30 +02005549
Guido van Rossumad0ee831995-03-01 10:34:45 +00005550#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005551PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005552"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005553Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005554
Barry Warsaw53699e91996-12-10 23:23:01 +00005555static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005556posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005557{
Victor Stinner8c62be82010-05-06 00:08:46 +00005558 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005559}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005560#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005561
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005562
Guido van Rossumad0ee831995-03-01 10:34:45 +00005563#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005564PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005565"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005566Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005567
Barry Warsaw53699e91996-12-10 23:23:01 +00005568static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005569posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005570{
Victor Stinner8c62be82010-05-06 00:08:46 +00005571 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005572}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005573#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005574
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005575
Guido van Rossumad0ee831995-03-01 10:34:45 +00005576#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005577PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005578"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005579Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005580
Barry Warsaw53699e91996-12-10 23:23:01 +00005581static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005582posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005583{
Victor Stinner8c62be82010-05-06 00:08:46 +00005584 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005585}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005586#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005587
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005588
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005589PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005590"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005591Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005592
Barry Warsaw53699e91996-12-10 23:23:01 +00005593static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005594posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005595{
Victor Stinner8c62be82010-05-06 00:08:46 +00005596 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005597}
5598
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005599#ifdef HAVE_GETGROUPLIST
5600PyDoc_STRVAR(posix_getgrouplist__doc__,
5601"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5602Returns a list of groups to which a user belongs.\n\n\
5603 user: username to lookup\n\
5604 group: base group id of the user");
5605
5606static PyObject *
5607posix_getgrouplist(PyObject *self, PyObject *args)
5608{
5609#ifdef NGROUPS_MAX
5610#define MAX_GROUPS NGROUPS_MAX
5611#else
5612 /* defined to be 16 on Solaris7, so this should be a small number */
5613#define MAX_GROUPS 64
5614#endif
5615
5616 const char *user;
5617 int i, ngroups;
5618 PyObject *list;
5619#ifdef __APPLE__
5620 int *groups, basegid;
5621#else
5622 gid_t *groups, basegid;
5623#endif
5624 ngroups = MAX_GROUPS;
5625
5626 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5627 return NULL;
5628
5629#ifdef __APPLE__
5630 groups = PyMem_Malloc(ngroups * sizeof(int));
5631#else
5632 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5633#endif
5634 if (groups == NULL)
5635 return PyErr_NoMemory();
5636
5637 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5638 PyMem_Del(groups);
5639 return posix_error();
5640 }
5641
5642 list = PyList_New(ngroups);
5643 if (list == NULL) {
5644 PyMem_Del(groups);
5645 return NULL;
5646 }
5647
5648 for (i = 0; i < ngroups; i++) {
5649 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5650 if (o == NULL) {
5651 Py_DECREF(list);
5652 PyMem_Del(groups);
5653 return NULL;
5654 }
5655 PyList_SET_ITEM(list, i, o);
5656 }
5657
5658 PyMem_Del(groups);
5659
5660 return list;
5661}
5662#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005663
Fred Drakec9680921999-12-13 16:37:25 +00005664#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005665PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005666"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005668
5669static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005670posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005671{
5672 PyObject *result = NULL;
5673
Fred Drakec9680921999-12-13 16:37:25 +00005674#ifdef NGROUPS_MAX
5675#define MAX_GROUPS NGROUPS_MAX
5676#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005677 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005678#define MAX_GROUPS 64
5679#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005680 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005681
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005682 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005683 * This is a helper variable to store the intermediate result when
5684 * that happens.
5685 *
5686 * To keep the code readable the OSX behaviour is unconditional,
5687 * according to the POSIX spec this should be safe on all unix-y
5688 * systems.
5689 */
5690 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005691 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005692
Victor Stinner8c62be82010-05-06 00:08:46 +00005693 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005694 if (n < 0) {
5695 if (errno == EINVAL) {
5696 n = getgroups(0, NULL);
5697 if (n == -1) {
5698 return posix_error();
5699 }
5700 if (n == 0) {
5701 /* Avoid malloc(0) */
5702 alt_grouplist = grouplist;
5703 } else {
5704 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5705 if (alt_grouplist == NULL) {
5706 errno = EINVAL;
5707 return posix_error();
5708 }
5709 n = getgroups(n, alt_grouplist);
5710 if (n == -1) {
5711 PyMem_Free(alt_grouplist);
5712 return posix_error();
5713 }
5714 }
5715 } else {
5716 return posix_error();
5717 }
5718 }
5719 result = PyList_New(n);
5720 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005721 int i;
5722 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005723 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005724 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005725 Py_DECREF(result);
5726 result = NULL;
5727 break;
Fred Drakec9680921999-12-13 16:37:25 +00005728 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005729 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005730 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005731 }
5732
5733 if (alt_grouplist != grouplist) {
5734 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005735 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005736
Fred Drakec9680921999-12-13 16:37:25 +00005737 return result;
5738}
5739#endif
5740
Antoine Pitroub7572f02009-12-02 20:46:48 +00005741#ifdef HAVE_INITGROUPS
5742PyDoc_STRVAR(posix_initgroups__doc__,
5743"initgroups(username, gid) -> None\n\n\
5744Call the system initgroups() to initialize the group access list with all of\n\
5745the groups of which the specified username is a member, plus the specified\n\
5746group id.");
5747
5748static PyObject *
5749posix_initgroups(PyObject *self, PyObject *args)
5750{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005751 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005752 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005753 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005754 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005755
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005756 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5757 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005758 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005759 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005760
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005761 res = initgroups(username, (gid_t) gid);
5762 Py_DECREF(oname);
5763 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005764 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005765
Victor Stinner8c62be82010-05-06 00:08:46 +00005766 Py_INCREF(Py_None);
5767 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005768}
5769#endif
5770
Martin v. Löwis606edc12002-06-13 21:09:11 +00005771#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005772PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005773"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005774Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005775
5776static PyObject *
5777posix_getpgid(PyObject *self, PyObject *args)
5778{
Victor Stinner8c62be82010-05-06 00:08:46 +00005779 pid_t pid, pgid;
5780 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5781 return NULL;
5782 pgid = getpgid(pid);
5783 if (pgid < 0)
5784 return posix_error();
5785 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005786}
5787#endif /* HAVE_GETPGID */
5788
5789
Guido van Rossumb6775db1994-08-01 11:34:53 +00005790#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005791PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005792"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005793Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005794
Barry Warsaw53699e91996-12-10 23:23:01 +00005795static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005796posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005797{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005798#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005799 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005800#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005801 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005802#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005803}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005804#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005805
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005806
Guido van Rossumb6775db1994-08-01 11:34:53 +00005807#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005808PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005809"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005810Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005811
Barry Warsaw53699e91996-12-10 23:23:01 +00005812static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005813posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005814{
Guido van Rossum64933891994-10-20 21:56:42 +00005815#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005816 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005817#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005818 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005819#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005820 return posix_error();
5821 Py_INCREF(Py_None);
5822 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005823}
5824
Guido van Rossumb6775db1994-08-01 11:34:53 +00005825#endif /* HAVE_SETPGRP */
5826
Guido van Rossumad0ee831995-03-01 10:34:45 +00005827#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005828
5829#ifdef MS_WINDOWS
5830#include <tlhelp32.h>
5831
5832static PyObject*
5833win32_getppid()
5834{
5835 HANDLE snapshot;
5836 pid_t mypid;
5837 PyObject* result = NULL;
5838 BOOL have_record;
5839 PROCESSENTRY32 pe;
5840
5841 mypid = getpid(); /* This function never fails */
5842
5843 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5844 if (snapshot == INVALID_HANDLE_VALUE)
5845 return PyErr_SetFromWindowsErr(GetLastError());
5846
5847 pe.dwSize = sizeof(pe);
5848 have_record = Process32First(snapshot, &pe);
5849 while (have_record) {
5850 if (mypid == (pid_t)pe.th32ProcessID) {
5851 /* We could cache the ulong value in a static variable. */
5852 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5853 break;
5854 }
5855
5856 have_record = Process32Next(snapshot, &pe);
5857 }
5858
5859 /* If our loop exits and our pid was not found (result will be NULL)
5860 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5861 * error anyway, so let's raise it. */
5862 if (!result)
5863 result = PyErr_SetFromWindowsErr(GetLastError());
5864
5865 CloseHandle(snapshot);
5866
5867 return result;
5868}
5869#endif /*MS_WINDOWS*/
5870
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005871PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005872"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005873Return the parent's process id. If the parent process has already exited,\n\
5874Windows machines will still return its id; others systems will return the id\n\
5875of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005876
Barry Warsaw53699e91996-12-10 23:23:01 +00005877static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005878posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005879{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005880#ifdef MS_WINDOWS
5881 return win32_getppid();
5882#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005883 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005884#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005885}
5886#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005888
Fred Drake12c6e2d1999-12-14 21:25:03 +00005889#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005890PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005891"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005892Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005893
5894static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005895posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005896{
Victor Stinner8c62be82010-05-06 00:08:46 +00005897 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005898#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005899 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005900 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005901
5902 if (GetUserNameW(user_name, &num_chars)) {
5903 /* num_chars is the number of unicode chars plus null terminator */
5904 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005905 }
5906 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005907 result = PyErr_SetFromWindowsErr(GetLastError());
5908#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005909 char *name;
5910 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005911
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 errno = 0;
5913 name = getlogin();
5914 if (name == NULL) {
5915 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005916 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005917 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005918 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 }
5920 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005921 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005922 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005923#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005924 return result;
5925}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005926#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005927
Guido van Rossumad0ee831995-03-01 10:34:45 +00005928#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005929PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005930"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005931Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005932
Barry Warsaw53699e91996-12-10 23:23:01 +00005933static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005934posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005935{
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005937}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005938#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005939
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005940
Guido van Rossumad0ee831995-03-01 10:34:45 +00005941#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005942PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005943"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005944Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005945
Barry Warsaw53699e91996-12-10 23:23:01 +00005946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005947posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005948{
Victor Stinner8c62be82010-05-06 00:08:46 +00005949 pid_t pid;
5950 int sig;
5951 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5952 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 if (kill(pid, sig) == -1)
5954 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005955 Py_INCREF(Py_None);
5956 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005957}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005958#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005959
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005960#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005961PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005962"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005963Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005964
5965static PyObject *
5966posix_killpg(PyObject *self, PyObject *args)
5967{
Victor Stinner8c62be82010-05-06 00:08:46 +00005968 int sig;
5969 pid_t pgid;
5970 /* XXX some man pages make the `pgid` parameter an int, others
5971 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5972 take the same type. Moreover, pid_t is always at least as wide as
5973 int (else compilation of this module fails), which is safe. */
5974 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5975 return NULL;
5976 if (killpg(pgid, sig) == -1)
5977 return posix_error();
5978 Py_INCREF(Py_None);
5979 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005980}
5981#endif
5982
Brian Curtineb24d742010-04-12 17:16:38 +00005983#ifdef MS_WINDOWS
5984PyDoc_STRVAR(win32_kill__doc__,
5985"kill(pid, sig)\n\n\
5986Kill a process with a signal.");
5987
5988static PyObject *
5989win32_kill(PyObject *self, PyObject *args)
5990{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005991 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005992 DWORD pid, sig, err;
5993 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005994
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5996 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005997
Victor Stinner8c62be82010-05-06 00:08:46 +00005998 /* Console processes which share a common console can be sent CTRL+C or
5999 CTRL+BREAK events, provided they handle said events. */
6000 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6001 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6002 err = GetLastError();
6003 PyErr_SetFromWindowsErr(err);
6004 }
6005 else
6006 Py_RETURN_NONE;
6007 }
Brian Curtineb24d742010-04-12 17:16:38 +00006008
Victor Stinner8c62be82010-05-06 00:08:46 +00006009 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6010 attempt to open and terminate the process. */
6011 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6012 if (handle == NULL) {
6013 err = GetLastError();
6014 return PyErr_SetFromWindowsErr(err);
6015 }
Brian Curtineb24d742010-04-12 17:16:38 +00006016
Victor Stinner8c62be82010-05-06 00:08:46 +00006017 if (TerminateProcess(handle, sig) == 0) {
6018 err = GetLastError();
6019 result = PyErr_SetFromWindowsErr(err);
6020 } else {
6021 Py_INCREF(Py_None);
6022 result = Py_None;
6023 }
Brian Curtineb24d742010-04-12 17:16:38 +00006024
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 CloseHandle(handle);
6026 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006027}
6028#endif /* MS_WINDOWS */
6029
Guido van Rossumc0125471996-06-28 18:55:32 +00006030#ifdef HAVE_PLOCK
6031
6032#ifdef HAVE_SYS_LOCK_H
6033#include <sys/lock.h>
6034#endif
6035
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006036PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006037"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006038Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006039
Barry Warsaw53699e91996-12-10 23:23:01 +00006040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006041posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006042{
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 int op;
6044 if (!PyArg_ParseTuple(args, "i:plock", &op))
6045 return NULL;
6046 if (plock(op) == -1)
6047 return posix_error();
6048 Py_INCREF(Py_None);
6049 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006050}
6051#endif
6052
Guido van Rossumb6775db1994-08-01 11:34:53 +00006053#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006054PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006055"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006056Set the current process's user id.");
6057
Barry Warsaw53699e91996-12-10 23:23:01 +00006058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006059posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006060{
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 long uid_arg;
6062 uid_t uid;
6063 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6064 return NULL;
6065 uid = uid_arg;
6066 if (uid != uid_arg) {
6067 PyErr_SetString(PyExc_OverflowError, "user id too big");
6068 return NULL;
6069 }
6070 if (setuid(uid) < 0)
6071 return posix_error();
6072 Py_INCREF(Py_None);
6073 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006074}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006075#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006077
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006078#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006080"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081Set the current process's effective user id.");
6082
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006083static PyObject *
6084posix_seteuid (PyObject *self, PyObject *args)
6085{
Victor Stinner8c62be82010-05-06 00:08:46 +00006086 long euid_arg;
6087 uid_t euid;
6088 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6089 return NULL;
6090 euid = euid_arg;
6091 if (euid != euid_arg) {
6092 PyErr_SetString(PyExc_OverflowError, "user id too big");
6093 return NULL;
6094 }
6095 if (seteuid(euid) < 0) {
6096 return posix_error();
6097 } else {
6098 Py_INCREF(Py_None);
6099 return Py_None;
6100 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006101}
6102#endif /* HAVE_SETEUID */
6103
6104#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006105PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006106"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006107Set the current process's effective group id.");
6108
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006109static PyObject *
6110posix_setegid (PyObject *self, PyObject *args)
6111{
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 long egid_arg;
6113 gid_t egid;
6114 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6115 return NULL;
6116 egid = egid_arg;
6117 if (egid != egid_arg) {
6118 PyErr_SetString(PyExc_OverflowError, "group id too big");
6119 return NULL;
6120 }
6121 if (setegid(egid) < 0) {
6122 return posix_error();
6123 } else {
6124 Py_INCREF(Py_None);
6125 return Py_None;
6126 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006127}
6128#endif /* HAVE_SETEGID */
6129
6130#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006131PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006132"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133Set the current process's real and effective user ids.");
6134
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006135static PyObject *
6136posix_setreuid (PyObject *self, PyObject *args)
6137{
Victor Stinner8c62be82010-05-06 00:08:46 +00006138 long ruid_arg, euid_arg;
6139 uid_t ruid, euid;
6140 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6141 return NULL;
6142 if (ruid_arg == -1)
6143 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6144 else
6145 ruid = ruid_arg; /* otherwise, assign from our long */
6146 if (euid_arg == -1)
6147 euid = (uid_t)-1;
6148 else
6149 euid = euid_arg;
6150 if ((euid_arg != -1 && euid != euid_arg) ||
6151 (ruid_arg != -1 && ruid != ruid_arg)) {
6152 PyErr_SetString(PyExc_OverflowError, "user id too big");
6153 return NULL;
6154 }
6155 if (setreuid(ruid, euid) < 0) {
6156 return posix_error();
6157 } else {
6158 Py_INCREF(Py_None);
6159 return Py_None;
6160 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006161}
6162#endif /* HAVE_SETREUID */
6163
6164#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006165PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006166"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006167Set the current process's real and effective group ids.");
6168
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006169static PyObject *
6170posix_setregid (PyObject *self, PyObject *args)
6171{
Victor Stinner8c62be82010-05-06 00:08:46 +00006172 long rgid_arg, egid_arg;
6173 gid_t rgid, egid;
6174 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6175 return NULL;
6176 if (rgid_arg == -1)
6177 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6178 else
6179 rgid = rgid_arg; /* otherwise, assign from our long */
6180 if (egid_arg == -1)
6181 egid = (gid_t)-1;
6182 else
6183 egid = egid_arg;
6184 if ((egid_arg != -1 && egid != egid_arg) ||
6185 (rgid_arg != -1 && rgid != rgid_arg)) {
6186 PyErr_SetString(PyExc_OverflowError, "group id too big");
6187 return NULL;
6188 }
6189 if (setregid(rgid, egid) < 0) {
6190 return posix_error();
6191 } else {
6192 Py_INCREF(Py_None);
6193 return Py_None;
6194 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006195}
6196#endif /* HAVE_SETREGID */
6197
Guido van Rossumb6775db1994-08-01 11:34:53 +00006198#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006199PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006200"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006201Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006202
Barry Warsaw53699e91996-12-10 23:23:01 +00006203static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006204posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006205{
Victor Stinner8c62be82010-05-06 00:08:46 +00006206 long gid_arg;
6207 gid_t gid;
6208 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6209 return NULL;
6210 gid = gid_arg;
6211 if (gid != gid_arg) {
6212 PyErr_SetString(PyExc_OverflowError, "group id too big");
6213 return NULL;
6214 }
6215 if (setgid(gid) < 0)
6216 return posix_error();
6217 Py_INCREF(Py_None);
6218 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006219}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006220#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006221
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006222#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006223PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006224"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006225Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006226
6227static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006228posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006229{
Victor Stinner8c62be82010-05-06 00:08:46 +00006230 int i, len;
6231 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006232
Victor Stinner8c62be82010-05-06 00:08:46 +00006233 if (!PySequence_Check(groups)) {
6234 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6235 return NULL;
6236 }
6237 len = PySequence_Size(groups);
6238 if (len > MAX_GROUPS) {
6239 PyErr_SetString(PyExc_ValueError, "too many groups");
6240 return NULL;
6241 }
6242 for(i = 0; i < len; i++) {
6243 PyObject *elem;
6244 elem = PySequence_GetItem(groups, i);
6245 if (!elem)
6246 return NULL;
6247 if (!PyLong_Check(elem)) {
6248 PyErr_SetString(PyExc_TypeError,
6249 "groups must be integers");
6250 Py_DECREF(elem);
6251 return NULL;
6252 } else {
6253 unsigned long x = PyLong_AsUnsignedLong(elem);
6254 if (PyErr_Occurred()) {
6255 PyErr_SetString(PyExc_TypeError,
6256 "group id too big");
6257 Py_DECREF(elem);
6258 return NULL;
6259 }
6260 grouplist[i] = x;
6261 /* read back the value to see if it fitted in gid_t */
6262 if (grouplist[i] != x) {
6263 PyErr_SetString(PyExc_TypeError,
6264 "group id too big");
6265 Py_DECREF(elem);
6266 return NULL;
6267 }
6268 }
6269 Py_DECREF(elem);
6270 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006271
Victor Stinner8c62be82010-05-06 00:08:46 +00006272 if (setgroups(len, grouplist) < 0)
6273 return posix_error();
6274 Py_INCREF(Py_None);
6275 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006276}
6277#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006278
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006279#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6280static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006281wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006282{
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 PyObject *result;
6284 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006285 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006286
Victor Stinner8c62be82010-05-06 00:08:46 +00006287 if (pid == -1)
6288 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006289
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 if (struct_rusage == NULL) {
6291 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6292 if (m == NULL)
6293 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006294 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006295 Py_DECREF(m);
6296 if (struct_rusage == NULL)
6297 return NULL;
6298 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006299
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6301 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6302 if (!result)
6303 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006304
6305#ifndef doubletime
6306#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6307#endif
6308
Victor Stinner8c62be82010-05-06 00:08:46 +00006309 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006310 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006311 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006312 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006313#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006314 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6315 SET_INT(result, 2, ru->ru_maxrss);
6316 SET_INT(result, 3, ru->ru_ixrss);
6317 SET_INT(result, 4, ru->ru_idrss);
6318 SET_INT(result, 5, ru->ru_isrss);
6319 SET_INT(result, 6, ru->ru_minflt);
6320 SET_INT(result, 7, ru->ru_majflt);
6321 SET_INT(result, 8, ru->ru_nswap);
6322 SET_INT(result, 9, ru->ru_inblock);
6323 SET_INT(result, 10, ru->ru_oublock);
6324 SET_INT(result, 11, ru->ru_msgsnd);
6325 SET_INT(result, 12, ru->ru_msgrcv);
6326 SET_INT(result, 13, ru->ru_nsignals);
6327 SET_INT(result, 14, ru->ru_nvcsw);
6328 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006329#undef SET_INT
6330
Victor Stinner8c62be82010-05-06 00:08:46 +00006331 if (PyErr_Occurred()) {
6332 Py_DECREF(result);
6333 return NULL;
6334 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006335
Victor Stinner8c62be82010-05-06 00:08:46 +00006336 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006337}
6338#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6339
6340#ifdef HAVE_WAIT3
6341PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006342"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006343Wait for completion of a child process.");
6344
6345static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006346posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006347{
Victor Stinner8c62be82010-05-06 00:08:46 +00006348 pid_t pid;
6349 int options;
6350 struct rusage ru;
6351 WAIT_TYPE status;
6352 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006353
Victor Stinner4195b5c2012-02-08 23:03:19 +01006354 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006356
Victor Stinner8c62be82010-05-06 00:08:46 +00006357 Py_BEGIN_ALLOW_THREADS
6358 pid = wait3(&status, options, &ru);
6359 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006360
Victor Stinner4195b5c2012-02-08 23:03:19 +01006361 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006362}
6363#endif /* HAVE_WAIT3 */
6364
6365#ifdef HAVE_WAIT4
6366PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006367"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006368Wait for completion of a given child process.");
6369
6370static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006371posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006372{
Victor Stinner8c62be82010-05-06 00:08:46 +00006373 pid_t pid;
6374 int options;
6375 struct rusage ru;
6376 WAIT_TYPE status;
6377 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006378
Victor Stinner4195b5c2012-02-08 23:03:19 +01006379 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006381
Victor Stinner8c62be82010-05-06 00:08:46 +00006382 Py_BEGIN_ALLOW_THREADS
6383 pid = wait4(pid, &status, options, &ru);
6384 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006385
Victor Stinner4195b5c2012-02-08 23:03:19 +01006386 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006387}
6388#endif /* HAVE_WAIT4 */
6389
Ross Lagerwall7807c352011-03-17 20:20:30 +02006390#if defined(HAVE_WAITID) && !defined(__APPLE__)
6391PyDoc_STRVAR(posix_waitid__doc__,
6392"waitid(idtype, id, options) -> waitid_result\n\n\
6393Wait for the completion of one or more child processes.\n\n\
6394idtype can be P_PID, P_PGID or P_ALL.\n\
6395id specifies the pid to wait on.\n\
6396options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6397or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6398Returns either waitid_result or None if WNOHANG is specified and there are\n\
6399no children in a waitable state.");
6400
6401static PyObject *
6402posix_waitid(PyObject *self, PyObject *args)
6403{
6404 PyObject *result;
6405 idtype_t idtype;
6406 id_t id;
6407 int options, res;
6408 siginfo_t si;
6409 si.si_pid = 0;
6410 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6411 return NULL;
6412 Py_BEGIN_ALLOW_THREADS
6413 res = waitid(idtype, id, &si, options);
6414 Py_END_ALLOW_THREADS
6415 if (res == -1)
6416 return posix_error();
6417
6418 if (si.si_pid == 0)
6419 Py_RETURN_NONE;
6420
6421 result = PyStructSequence_New(&WaitidResultType);
6422 if (!result)
6423 return NULL;
6424
6425 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6426 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6427 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6428 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6429 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6430 if (PyErr_Occurred()) {
6431 Py_DECREF(result);
6432 return NULL;
6433 }
6434
6435 return result;
6436}
6437#endif
6438
Guido van Rossumb6775db1994-08-01 11:34:53 +00006439#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006440PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006441"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006442Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006443
Barry Warsaw53699e91996-12-10 23:23:01 +00006444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006445posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006446{
Victor Stinner8c62be82010-05-06 00:08:46 +00006447 pid_t pid;
6448 int options;
6449 WAIT_TYPE status;
6450 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006451
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6453 return NULL;
6454 Py_BEGIN_ALLOW_THREADS
6455 pid = waitpid(pid, &status, options);
6456 Py_END_ALLOW_THREADS
6457 if (pid == -1)
6458 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006459
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006461}
6462
Tim Petersab034fa2002-02-01 11:27:43 +00006463#elif defined(HAVE_CWAIT)
6464
6465/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006466PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006467"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006468"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006469
6470static PyObject *
6471posix_waitpid(PyObject *self, PyObject *args)
6472{
Victor Stinner8c62be82010-05-06 00:08:46 +00006473 Py_intptr_t pid;
6474 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006475
Victor Stinner8c62be82010-05-06 00:08:46 +00006476 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6477 return NULL;
6478 Py_BEGIN_ALLOW_THREADS
6479 pid = _cwait(&status, pid, options);
6480 Py_END_ALLOW_THREADS
6481 if (pid == -1)
6482 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006483
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 /* shift the status left a byte so this is more like the POSIX waitpid */
6485 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006486}
6487#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006488
Guido van Rossumad0ee831995-03-01 10:34:45 +00006489#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006490PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006491"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006492Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006493
Barry Warsaw53699e91996-12-10 23:23:01 +00006494static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006495posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006496{
Victor Stinner8c62be82010-05-06 00:08:46 +00006497 pid_t pid;
6498 WAIT_TYPE status;
6499 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006500
Victor Stinner8c62be82010-05-06 00:08:46 +00006501 Py_BEGIN_ALLOW_THREADS
6502 pid = wait(&status);
6503 Py_END_ALLOW_THREADS
6504 if (pid == -1)
6505 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006506
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006508}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006509#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006510
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006511
Larry Hastings9cf065c2012-06-22 16:30:09 -07006512#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6513PyDoc_STRVAR(readlink__doc__,
6514"readlink(path, *, dir_fd=None) -> path\n\n\
6515Return a string representing the path to which the symbolic link points.\n\
6516\n\
6517If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6518 and path should be relative; path will then be relative to that directory.\n\
6519dir_fd may not be implemented on your platform.\n\
6520 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006521#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006522
Guido van Rossumb6775db1994-08-01 11:34:53 +00006523#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006524
Barry Warsaw53699e91996-12-10 23:23:01 +00006525static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006526posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006527{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006528 path_t path;
6529 int dir_fd = DEFAULT_DIR_FD;
6530 char buffer[MAXPATHLEN];
6531 ssize_t length;
6532 PyObject *return_value = NULL;
6533 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006534
Larry Hastings9cf065c2012-06-22 16:30:09 -07006535 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006536 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006537 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6538 path_converter, &path,
6539#ifdef HAVE_READLINKAT
6540 dir_fd_converter, &dir_fd
6541#else
6542 dir_fd_unavailable, &dir_fd
6543#endif
6544 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006546
Victor Stinner8c62be82010-05-06 00:08:46 +00006547 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006548#ifdef HAVE_READLINKAT
6549 if (dir_fd != DEFAULT_DIR_FD)
6550 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006551 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006552#endif
6553 length = readlink(path.narrow, buffer, sizeof(buffer));
6554 Py_END_ALLOW_THREADS
6555
6556 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006557 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006558 goto exit;
6559 }
6560
6561 if (PyUnicode_Check(path.object))
6562 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6563 else
6564 return_value = PyBytes_FromStringAndSize(buffer, length);
6565exit:
6566 path_cleanup(&path);
6567 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006568}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006569
6570
Guido van Rossumb6775db1994-08-01 11:34:53 +00006571#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006572
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006573
Larry Hastings9cf065c2012-06-22 16:30:09 -07006574#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006575PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006576"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
6577Create a symbolic link pointing to src named dst.\n\n\
6578target_is_directory is required on Windows if the target is to be\n\
6579 interpreted as a directory. (On Windows, symlink requires\n\
6580 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
6581 target_is_directory is ignored on non-Windows platforms.\n\
6582\n\
6583If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6584 and path should be relative; path will then be relative to that directory.\n\
6585dir_fd may not be implemented on your platform.\n\
6586 If it is unavailable, using it will raise a NotImplementedError.");
6587
6588#if defined(MS_WINDOWS)
6589
6590/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6591static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
6592static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
6593static int
6594check_CreateSymbolicLink()
6595{
6596 HINSTANCE hKernel32;
6597 /* only recheck */
6598 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
6599 return 1;
6600 hKernel32 = GetModuleHandleW(L"KERNEL32");
6601 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6602 "CreateSymbolicLinkW");
6603 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
6604 "CreateSymbolicLinkA");
6605 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
6606}
6607
6608#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006609
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006610static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006611posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006612{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006613 path_t src;
6614 path_t dst;
6615 int dir_fd = DEFAULT_DIR_FD;
6616 int target_is_directory = 0;
6617 static char *keywords[] = {"src", "dst", "target_is_directory",
6618 "dir_fd", NULL};
6619 PyObject *return_value;
6620#ifdef MS_WINDOWS
6621 DWORD result;
6622#else
6623 int result;
6624#endif
6625
6626 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01006627 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006628 src.argument_name = "src";
6629 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01006630 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006631 dst.argument_name = "dst";
6632
6633#ifdef MS_WINDOWS
6634 if (!check_CreateSymbolicLink()) {
6635 PyErr_SetString(PyExc_NotImplementedError,
6636 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006637 return NULL;
6638 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006639 if (!win32_can_symlink) {
6640 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006641 return NULL;
6642 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006643#endif
6644
6645 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
6646 keywords,
6647 path_converter, &src,
6648 path_converter, &dst,
6649 &target_is_directory,
6650#ifdef HAVE_SYMLINKAT
6651 dir_fd_converter, &dir_fd
6652#else
6653 dir_fd_unavailable, &dir_fd
6654#endif
6655 ))
6656 return NULL;
6657
6658 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
6659 PyErr_SetString(PyExc_ValueError,
6660 "symlink: src and dst must be the same type");
6661 return_value = NULL;
6662 goto exit;
6663 }
6664
6665#ifdef MS_WINDOWS
6666 Py_BEGIN_ALLOW_THREADS
6667 if (dst.wide)
6668 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
6669 target_is_directory);
6670 else
6671 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
6672 target_is_directory);
6673 Py_END_ALLOW_THREADS
6674
6675 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01006676 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006677 goto exit;
6678 }
6679
6680#else
6681
6682 Py_BEGIN_ALLOW_THREADS
6683#if HAVE_SYMLINKAT
6684 if (dir_fd != DEFAULT_DIR_FD)
6685 result = symlinkat(src.narrow, dir_fd, dst.narrow);
6686 else
6687#endif
6688 result = symlink(src.narrow, dst.narrow);
6689 Py_END_ALLOW_THREADS
6690
6691 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01006692 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006693 goto exit;
6694 }
6695#endif
6696
6697 return_value = Py_None;
6698 Py_INCREF(Py_None);
6699 goto exit; /* silence "unused label" warning */
6700exit:
6701 path_cleanup(&src);
6702 path_cleanup(&dst);
6703 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006704}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006705
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006706#endif /* HAVE_SYMLINK */
6707
Larry Hastings9cf065c2012-06-22 16:30:09 -07006708
Brian Curtind40e6f72010-07-08 21:39:08 +00006709#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6710
Brian Curtind40e6f72010-07-08 21:39:08 +00006711static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006712win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00006713{
6714 wchar_t *path;
6715 DWORD n_bytes_returned;
6716 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006717 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006718 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00006719 HANDLE reparse_point_handle;
6720
6721 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6722 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6723 wchar_t *print_name;
6724
Larry Hastings9cf065c2012-06-22 16:30:09 -07006725 static char *keywords[] = {"path", "dir_fd", NULL};
6726
6727 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
6728 &po,
6729 dir_fd_unavailable, &dir_fd
6730 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02006731 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006732
Victor Stinnereb5657a2011-09-30 01:44:27 +02006733 path = PyUnicode_AsUnicode(po);
6734 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006735 return NULL;
6736
6737 /* First get a handle to the reparse point */
6738 Py_BEGIN_ALLOW_THREADS
6739 reparse_point_handle = CreateFileW(
6740 path,
6741 0,
6742 0,
6743 0,
6744 OPEN_EXISTING,
6745 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6746 0);
6747 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006748
Brian Curtind40e6f72010-07-08 21:39:08 +00006749 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006750 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006751
Brian Curtind40e6f72010-07-08 21:39:08 +00006752 Py_BEGIN_ALLOW_THREADS
6753 /* New call DeviceIoControl to read the reparse point */
6754 io_result = DeviceIoControl(
6755 reparse_point_handle,
6756 FSCTL_GET_REPARSE_POINT,
6757 0, 0, /* in buffer */
6758 target_buffer, sizeof(target_buffer),
6759 &n_bytes_returned,
6760 0 /* we're not using OVERLAPPED_IO */
6761 );
6762 CloseHandle(reparse_point_handle);
6763 Py_END_ALLOW_THREADS
6764
6765 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006766 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006767
6768 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6769 {
6770 PyErr_SetString(PyExc_ValueError,
6771 "not a symbolic link");
6772 return NULL;
6773 }
Brian Curtin74e45612010-07-09 15:58:59 +00006774 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6775 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6776
6777 result = PyUnicode_FromWideChar(print_name,
6778 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006779 return result;
6780}
6781
6782#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6783
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006784
Larry Hastings605a62d2012-06-24 04:33:36 -07006785static PyStructSequence_Field times_result_fields[] = {
6786 {"user", "user time"},
6787 {"system", "system time"},
6788 {"children_user", "user time of children"},
6789 {"children_system", "system time of children"},
6790 {"elapsed", "elapsed time since an arbitrary point in the past"},
6791 {NULL}
6792};
6793
6794PyDoc_STRVAR(times_result__doc__,
6795"times_result: Result from os.times().\n\n\
6796This object may be accessed either as a tuple of\n\
6797 (user, system, children_user, children_system, elapsed),\n\
6798or via the attributes user, system, children_user, children_system,\n\
6799and elapsed.\n\
6800\n\
6801See os.times for more information.");
6802
6803static PyStructSequence_Desc times_result_desc = {
6804 "times_result", /* name */
6805 times_result__doc__, /* doc */
6806 times_result_fields,
6807 5
6808};
6809
6810static PyTypeObject TimesResultType;
6811
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006812#ifdef MS_WINDOWS
6813#define HAVE_TIMES /* mandatory, for the method table */
6814#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07006815
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006816#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07006817
6818static PyObject *
6819build_times_result(double user, double system,
6820 double children_user, double children_system,
6821 double elapsed)
6822{
6823 PyObject *value = PyStructSequence_New(&TimesResultType);
6824 if (value == NULL)
6825 return NULL;
6826
6827#define SET(i, field) \
6828 { \
6829 PyObject *o = PyFloat_FromDouble(field); \
6830 if (!o) { \
6831 Py_DECREF(value); \
6832 return NULL; \
6833 } \
6834 PyStructSequence_SET_ITEM(value, i, o); \
6835 } \
6836
6837 SET(0, user);
6838 SET(1, system);
6839 SET(2, children_user);
6840 SET(3, children_system);
6841 SET(4, elapsed);
6842
6843#undef SET
6844
6845 return value;
6846}
6847
6848PyDoc_STRVAR(posix_times__doc__,
6849"times() -> times_result\n\n\
6850Return an object containing floating point numbers indicating process\n\
6851times. The object behaves like a named tuple with these fields:\n\
6852 (utime, stime, cutime, cstime, elapsed_time)");
6853
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006854#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00006855static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006856posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006857{
Victor Stinner8c62be82010-05-06 00:08:46 +00006858 FILETIME create, exit, kernel, user;
6859 HANDLE hProc;
6860 hProc = GetCurrentProcess();
6861 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6862 /* The fields of a FILETIME structure are the hi and lo part
6863 of a 64-bit value expressed in 100 nanosecond units.
6864 1e7 is one second in such units; 1e-7 the inverse.
6865 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6866 */
Larry Hastings605a62d2012-06-24 04:33:36 -07006867 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 (double)(user.dwHighDateTime*429.4967296 +
6869 user.dwLowDateTime*1e-7),
6870 (double)(kernel.dwHighDateTime*429.4967296 +
6871 kernel.dwLowDateTime*1e-7),
6872 (double)0,
6873 (double)0,
6874 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006875}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006876#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006877#define NEED_TICKS_PER_SECOND
6878static long ticks_per_second = -1;
6879static PyObject *
6880posix_times(PyObject *self, PyObject *noargs)
6881{
6882 struct tms t;
6883 clock_t c;
6884 errno = 0;
6885 c = times(&t);
6886 if (c == (clock_t) -1)
6887 return posix_error();
6888 return build_times_result(
6889 (double)t.tms_utime / ticks_per_second,
6890 (double)t.tms_stime / ticks_per_second,
6891 (double)t.tms_cutime / ticks_per_second,
6892 (double)t.tms_cstime / ticks_per_second,
6893 (double)c / ticks_per_second);
6894}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006895#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006896
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006897#endif /* HAVE_TIMES */
6898
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006899
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006900#ifdef HAVE_GETSID
6901PyDoc_STRVAR(posix_getsid__doc__,
6902"getsid(pid) -> sid\n\n\
6903Call the system call getsid().");
6904
6905static PyObject *
6906posix_getsid(PyObject *self, PyObject *args)
6907{
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 pid_t pid;
6909 int sid;
6910 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6911 return NULL;
6912 sid = getsid(pid);
6913 if (sid < 0)
6914 return posix_error();
6915 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006916}
6917#endif /* HAVE_GETSID */
6918
6919
Guido van Rossumb6775db1994-08-01 11:34:53 +00006920#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006921PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006922"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006923Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006924
Barry Warsaw53699e91996-12-10 23:23:01 +00006925static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006926posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006927{
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 if (setsid() < 0)
6929 return posix_error();
6930 Py_INCREF(Py_None);
6931 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006932}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006933#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006934
Guido van Rossumb6775db1994-08-01 11:34:53 +00006935#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006936PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006937"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006938Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006939
Barry Warsaw53699e91996-12-10 23:23:01 +00006940static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006941posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006942{
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 pid_t pid;
6944 int pgrp;
6945 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6946 return NULL;
6947 if (setpgid(pid, pgrp) < 0)
6948 return posix_error();
6949 Py_INCREF(Py_None);
6950 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006951}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006952#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006954
Guido van Rossumb6775db1994-08-01 11:34:53 +00006955#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006956PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006957"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006958Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006959
Barry Warsaw53699e91996-12-10 23:23:01 +00006960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006961posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006962{
Victor Stinner8c62be82010-05-06 00:08:46 +00006963 int fd;
6964 pid_t pgid;
6965 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6966 return NULL;
6967 pgid = tcgetpgrp(fd);
6968 if (pgid < 0)
6969 return posix_error();
6970 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006971}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006972#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006973
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006974
Guido van Rossumb6775db1994-08-01 11:34:53 +00006975#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006976PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006977"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006978Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006979
Barry Warsaw53699e91996-12-10 23:23:01 +00006980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006981posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006982{
Victor Stinner8c62be82010-05-06 00:08:46 +00006983 int fd;
6984 pid_t pgid;
6985 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6986 return NULL;
6987 if (tcsetpgrp(fd, pgid) < 0)
6988 return posix_error();
6989 Py_INCREF(Py_None);
6990 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006991}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006992#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006993
Guido van Rossum687dd131993-05-17 08:34:16 +00006994/* Functions acting on file descriptors */
6995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006996PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006997"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
6998Open a file for low level IO. Returns a file handle (integer).\n\
6999\n\
7000If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7001 and path should be relative; path will then be relative to that directory.\n\
7002dir_fd may not be implemented on your platform.\n\
7003 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007004
Barry Warsaw53699e91996-12-10 23:23:01 +00007005static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007006posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007007{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007008 path_t path;
7009 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007011 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007013 PyObject *return_value = NULL;
7014 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007015
Larry Hastings9cf065c2012-06-22 16:30:09 -07007016 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007017 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007018 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7019 path_converter, &path,
7020 &flags, &mode,
7021#ifdef HAVE_OPENAT
7022 dir_fd_converter, &dir_fd
7023#else
7024 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007025#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007026 ))
7027 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007028
Victor Stinner8c62be82010-05-06 00:08:46 +00007029 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007030#ifdef MS_WINDOWS
7031 if (path.wide)
7032 fd = _wopen(path.wide, flags, mode);
7033 else
7034#endif
7035#ifdef HAVE_OPENAT
7036 if (dir_fd != DEFAULT_DIR_FD)
7037 fd = openat(dir_fd, path.narrow, flags, mode);
7038 else
7039#endif
7040 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007041 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007042
Larry Hastings9cf065c2012-06-22 16:30:09 -07007043 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007044 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007045 goto exit;
7046 }
7047
7048 return_value = PyLong_FromLong((long)fd);
7049
7050exit:
7051 path_cleanup(&path);
7052 return return_value;
7053}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007054
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007055PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007056"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007057Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007058
Barry Warsaw53699e91996-12-10 23:23:01 +00007059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007060posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007061{
Victor Stinner8c62be82010-05-06 00:08:46 +00007062 int fd, res;
7063 if (!PyArg_ParseTuple(args, "i:close", &fd))
7064 return NULL;
7065 if (!_PyVerify_fd(fd))
7066 return posix_error();
7067 Py_BEGIN_ALLOW_THREADS
7068 res = close(fd);
7069 Py_END_ALLOW_THREADS
7070 if (res < 0)
7071 return posix_error();
7072 Py_INCREF(Py_None);
7073 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007074}
7075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007076
Victor Stinner8c62be82010-05-06 00:08:46 +00007077PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007078"closerange(fd_low, fd_high)\n\n\
7079Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7080
7081static PyObject *
7082posix_closerange(PyObject *self, PyObject *args)
7083{
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 int fd_from, fd_to, i;
7085 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7086 return NULL;
7087 Py_BEGIN_ALLOW_THREADS
7088 for (i = fd_from; i < fd_to; i++)
7089 if (_PyVerify_fd(i))
7090 close(i);
7091 Py_END_ALLOW_THREADS
7092 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007093}
7094
7095
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007096PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007097"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007098Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007099
Barry Warsaw53699e91996-12-10 23:23:01 +00007100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007101posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007102{
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 int fd;
7104 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7105 return NULL;
7106 if (!_PyVerify_fd(fd))
7107 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007109 if (fd < 0)
7110 return posix_error();
7111 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007112}
7113
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007114
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007115PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007116"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007117Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007118
Barry Warsaw53699e91996-12-10 23:23:01 +00007119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007120posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007121{
Victor Stinner8c62be82010-05-06 00:08:46 +00007122 int fd, fd2, res;
7123 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7124 return NULL;
7125 if (!_PyVerify_fd_dup2(fd, fd2))
7126 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007128 if (res < 0)
7129 return posix_error();
7130 Py_INCREF(Py_None);
7131 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007132}
7133
Ross Lagerwall7807c352011-03-17 20:20:30 +02007134#ifdef HAVE_LOCKF
7135PyDoc_STRVAR(posix_lockf__doc__,
7136"lockf(fd, cmd, len)\n\n\
7137Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7138fd is an open file descriptor.\n\
7139cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7140F_TEST.\n\
7141len specifies the section of the file to lock.");
7142
7143static PyObject *
7144posix_lockf(PyObject *self, PyObject *args)
7145{
7146 int fd, cmd, res;
7147 off_t len;
7148 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7149 &fd, &cmd, _parse_off_t, &len))
7150 return NULL;
7151
7152 Py_BEGIN_ALLOW_THREADS
7153 res = lockf(fd, cmd, len);
7154 Py_END_ALLOW_THREADS
7155
7156 if (res < 0)
7157 return posix_error();
7158
7159 Py_RETURN_NONE;
7160}
7161#endif
7162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007163
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007164PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007165"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007166Set the current position of a file descriptor.\n\
7167Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007168
Barry Warsaw53699e91996-12-10 23:23:01 +00007169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007170posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007171{
Victor Stinner8c62be82010-05-06 00:08:46 +00007172 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007173#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007175#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007176 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007177#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007178 PyObject *posobj;
7179 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007181#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007182 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7183 switch (how) {
7184 case 0: how = SEEK_SET; break;
7185 case 1: how = SEEK_CUR; break;
7186 case 2: how = SEEK_END; break;
7187 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007188#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007189
Ross Lagerwall8e749672011-03-17 21:54:07 +02007190#if !defined(HAVE_LARGEFILE_SUPPORT)
7191 pos = PyLong_AsLong(posobj);
7192#else
7193 pos = PyLong_AsLongLong(posobj);
7194#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 if (PyErr_Occurred())
7196 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007197
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 if (!_PyVerify_fd(fd))
7199 return posix_error();
7200 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007201#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007202 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007203#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007205#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007206 Py_END_ALLOW_THREADS
7207 if (res < 0)
7208 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007209
7210#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007211 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007212#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007213 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007214#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007215}
7216
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007217
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007218PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007219"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007220Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007221
Barry Warsaw53699e91996-12-10 23:23:01 +00007222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007223posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007224{
Victor Stinner8c62be82010-05-06 00:08:46 +00007225 int fd, size;
7226 Py_ssize_t n;
7227 PyObject *buffer;
7228 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7229 return NULL;
7230 if (size < 0) {
7231 errno = EINVAL;
7232 return posix_error();
7233 }
7234 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7235 if (buffer == NULL)
7236 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007237 if (!_PyVerify_fd(fd)) {
7238 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007239 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007240 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007241 Py_BEGIN_ALLOW_THREADS
7242 n = read(fd, PyBytes_AS_STRING(buffer), size);
7243 Py_END_ALLOW_THREADS
7244 if (n < 0) {
7245 Py_DECREF(buffer);
7246 return posix_error();
7247 }
7248 if (n != size)
7249 _PyBytes_Resize(&buffer, n);
7250 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007251}
7252
Ross Lagerwall7807c352011-03-17 20:20:30 +02007253#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7254 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007255static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007256iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7257{
7258 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007259 Py_ssize_t blen, total = 0;
7260
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007261 *iov = PyMem_New(struct iovec, cnt);
7262 if (*iov == NULL) {
7263 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007264 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007265 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007266
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007267 *buf = PyMem_New(Py_buffer, cnt);
7268 if (*buf == NULL) {
7269 PyMem_Del(*iov);
7270 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007271 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007272 }
7273
7274 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007275 PyObject *item = PySequence_GetItem(seq, i);
7276 if (item == NULL)
7277 goto fail;
7278 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7279 Py_DECREF(item);
7280 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007281 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007282 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007283 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007284 blen = (*buf)[i].len;
7285 (*iov)[i].iov_len = blen;
7286 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007287 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007288 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007289
7290fail:
7291 PyMem_Del(*iov);
7292 for (j = 0; j < i; j++) {
7293 PyBuffer_Release(&(*buf)[j]);
7294 }
7295 PyMem_Del(*buf);
7296 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007297}
7298
7299static void
7300iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7301{
7302 int i;
7303 PyMem_Del(iov);
7304 for (i = 0; i < cnt; i++) {
7305 PyBuffer_Release(&buf[i]);
7306 }
7307 PyMem_Del(buf);
7308}
7309#endif
7310
Ross Lagerwall7807c352011-03-17 20:20:30 +02007311#ifdef HAVE_READV
7312PyDoc_STRVAR(posix_readv__doc__,
7313"readv(fd, buffers) -> bytesread\n\n\
7314Read from a file descriptor into a number of writable buffers. buffers\n\
7315is an arbitrary sequence of writable buffers.\n\
7316Returns the total number of bytes read.");
7317
7318static PyObject *
7319posix_readv(PyObject *self, PyObject *args)
7320{
7321 int fd, cnt;
7322 Py_ssize_t n;
7323 PyObject *seq;
7324 struct iovec *iov;
7325 Py_buffer *buf;
7326
7327 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7328 return NULL;
7329 if (!PySequence_Check(seq)) {
7330 PyErr_SetString(PyExc_TypeError,
7331 "readv() arg 2 must be a sequence");
7332 return NULL;
7333 }
7334 cnt = PySequence_Size(seq);
7335
7336 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7337 return NULL;
7338
7339 Py_BEGIN_ALLOW_THREADS
7340 n = readv(fd, iov, cnt);
7341 Py_END_ALLOW_THREADS
7342
7343 iov_cleanup(iov, buf, cnt);
7344 return PyLong_FromSsize_t(n);
7345}
7346#endif
7347
7348#ifdef HAVE_PREAD
7349PyDoc_STRVAR(posix_pread__doc__,
7350"pread(fd, buffersize, offset) -> string\n\n\
7351Read from a file descriptor, fd, at a position of offset. It will read up\n\
7352to buffersize number of bytes. The file offset remains unchanged.");
7353
7354static PyObject *
7355posix_pread(PyObject *self, PyObject *args)
7356{
7357 int fd, size;
7358 off_t offset;
7359 Py_ssize_t n;
7360 PyObject *buffer;
7361 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7362 return NULL;
7363
7364 if (size < 0) {
7365 errno = EINVAL;
7366 return posix_error();
7367 }
7368 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7369 if (buffer == NULL)
7370 return NULL;
7371 if (!_PyVerify_fd(fd)) {
7372 Py_DECREF(buffer);
7373 return posix_error();
7374 }
7375 Py_BEGIN_ALLOW_THREADS
7376 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7377 Py_END_ALLOW_THREADS
7378 if (n < 0) {
7379 Py_DECREF(buffer);
7380 return posix_error();
7381 }
7382 if (n != size)
7383 _PyBytes_Resize(&buffer, n);
7384 return buffer;
7385}
7386#endif
7387
7388PyDoc_STRVAR(posix_write__doc__,
7389"write(fd, string) -> byteswritten\n\n\
7390Write a string to a file descriptor.");
7391
7392static PyObject *
7393posix_write(PyObject *self, PyObject *args)
7394{
7395 Py_buffer pbuf;
7396 int fd;
7397 Py_ssize_t size, len;
7398
7399 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7400 return NULL;
7401 if (!_PyVerify_fd(fd)) {
7402 PyBuffer_Release(&pbuf);
7403 return posix_error();
7404 }
7405 len = pbuf.len;
7406 Py_BEGIN_ALLOW_THREADS
7407#if defined(MS_WIN64) || defined(MS_WINDOWS)
7408 if (len > INT_MAX)
7409 len = INT_MAX;
7410 size = write(fd, pbuf.buf, (int)len);
7411#else
7412 size = write(fd, pbuf.buf, len);
7413#endif
7414 Py_END_ALLOW_THREADS
7415 PyBuffer_Release(&pbuf);
7416 if (size < 0)
7417 return posix_error();
7418 return PyLong_FromSsize_t(size);
7419}
7420
7421#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007422PyDoc_STRVAR(posix_sendfile__doc__,
7423"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7424sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7425 -> byteswritten\n\
7426Copy nbytes bytes from file descriptor in to file descriptor out.");
7427
7428static PyObject *
7429posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7430{
7431 int in, out;
7432 Py_ssize_t ret;
7433 off_t offset;
7434
7435#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7436#ifndef __APPLE__
7437 Py_ssize_t len;
7438#endif
7439 PyObject *headers = NULL, *trailers = NULL;
7440 Py_buffer *hbuf, *tbuf;
7441 off_t sbytes;
7442 struct sf_hdtr sf;
7443 int flags = 0;
7444 sf.headers = NULL;
7445 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007446 static char *keywords[] = {"out", "in",
7447 "offset", "count",
7448 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007449
7450#ifdef __APPLE__
7451 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007452 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007453#else
7454 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007455 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007456#endif
7457 &headers, &trailers, &flags))
7458 return NULL;
7459 if (headers != NULL) {
7460 if (!PySequence_Check(headers)) {
7461 PyErr_SetString(PyExc_TypeError,
7462 "sendfile() headers must be a sequence or None");
7463 return NULL;
7464 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007465 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007466 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007467 if (sf.hdr_cnt > 0 &&
7468 !(i = iov_setup(&(sf.headers), &hbuf,
7469 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007470 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007471#ifdef __APPLE__
7472 sbytes += i;
7473#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007474 }
7475 }
7476 if (trailers != NULL) {
7477 if (!PySequence_Check(trailers)) {
7478 PyErr_SetString(PyExc_TypeError,
7479 "sendfile() trailers must be a sequence or None");
7480 return NULL;
7481 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007482 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007483 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007484 if (sf.trl_cnt > 0 &&
7485 !(i = iov_setup(&(sf.trailers), &tbuf,
7486 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007487 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007488#ifdef __APPLE__
7489 sbytes += i;
7490#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007491 }
7492 }
7493
7494 Py_BEGIN_ALLOW_THREADS
7495#ifdef __APPLE__
7496 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7497#else
7498 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7499#endif
7500 Py_END_ALLOW_THREADS
7501
7502 if (sf.headers != NULL)
7503 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7504 if (sf.trailers != NULL)
7505 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7506
7507 if (ret < 0) {
7508 if ((errno == EAGAIN) || (errno == EBUSY)) {
7509 if (sbytes != 0) {
7510 // some data has been sent
7511 goto done;
7512 }
7513 else {
7514 // no data has been sent; upper application is supposed
7515 // to retry on EAGAIN or EBUSY
7516 return posix_error();
7517 }
7518 }
7519 return posix_error();
7520 }
7521 goto done;
7522
7523done:
7524 #if !defined(HAVE_LARGEFILE_SUPPORT)
7525 return Py_BuildValue("l", sbytes);
7526 #else
7527 return Py_BuildValue("L", sbytes);
7528 #endif
7529
7530#else
7531 Py_ssize_t count;
7532 PyObject *offobj;
7533 static char *keywords[] = {"out", "in",
7534 "offset", "count", NULL};
7535 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7536 keywords, &out, &in, &offobj, &count))
7537 return NULL;
7538#ifdef linux
7539 if (offobj == Py_None) {
7540 Py_BEGIN_ALLOW_THREADS
7541 ret = sendfile(out, in, NULL, count);
7542 Py_END_ALLOW_THREADS
7543 if (ret < 0)
7544 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007545 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007546 }
7547#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007548 if (!_parse_off_t(offobj, &offset))
7549 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007550 Py_BEGIN_ALLOW_THREADS
7551 ret = sendfile(out, in, &offset, count);
7552 Py_END_ALLOW_THREADS
7553 if (ret < 0)
7554 return posix_error();
7555 return Py_BuildValue("n", ret);
7556#endif
7557}
7558#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007559
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007560PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007561"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007562Like stat(), but for an open file descriptor.\n\
7563Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007564
Barry Warsaw53699e91996-12-10 23:23:01 +00007565static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007566posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007567{
Victor Stinner8c62be82010-05-06 00:08:46 +00007568 int fd;
7569 STRUCT_STAT st;
7570 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007571 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007572 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007573#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007574 /* on OpenVMS we must ensure that all bytes are written to the file */
7575 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007576#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007577 Py_BEGIN_ALLOW_THREADS
7578 res = FSTAT(fd, &st);
7579 Py_END_ALLOW_THREADS
7580 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007581#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01007582 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00007583#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007585#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 }
Tim Peters5aa91602002-01-30 05:46:57 +00007587
Victor Stinner4195b5c2012-02-08 23:03:19 +01007588 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007589}
7590
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007591PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007592"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007593Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007594connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007595
7596static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007597posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007598{
Victor Stinner8c62be82010-05-06 00:08:46 +00007599 int fd;
7600 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7601 return NULL;
7602 if (!_PyVerify_fd(fd))
7603 return PyBool_FromLong(0);
7604 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007605}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007606
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007607#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007608PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007609"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007610Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007611
Barry Warsaw53699e91996-12-10 23:23:01 +00007612static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007613posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007614{
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007615#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 int fds[2];
7617 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 if (res != 0)
7620 return posix_error();
7621 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007622#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007623 HANDLE read, write;
7624 int read_fd, write_fd;
7625 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007627 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01007628 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007629 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7630 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7631 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007632#endif /* MS_WINDOWS */
Guido van Rossum687dd131993-05-17 08:34:16 +00007633}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007634#endif /* HAVE_PIPE */
7635
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007636#ifdef HAVE_PIPE2
7637PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007638"pipe2(flags) -> (read_end, write_end)\n\n\
7639Create a pipe with flags set atomically.\n\
7640flags can be constructed by ORing together one or more of these values:\n\
7641O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007642");
7643
7644static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007645posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007646{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007647 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007648 int fds[2];
7649 int res;
7650
Serhiy Storchaka78980432013-01-15 01:12:17 +02007651 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02007652 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007653 return NULL;
7654
7655 res = pipe2(fds, flags);
7656 if (res != 0)
7657 return posix_error();
7658 return Py_BuildValue("(ii)", fds[0], fds[1]);
7659}
7660#endif /* HAVE_PIPE2 */
7661
Ross Lagerwall7807c352011-03-17 20:20:30 +02007662#ifdef HAVE_WRITEV
7663PyDoc_STRVAR(posix_writev__doc__,
7664"writev(fd, buffers) -> byteswritten\n\n\
7665Write the contents of buffers to a file descriptor, where buffers is an\n\
7666arbitrary sequence of buffers.\n\
7667Returns the total bytes written.");
7668
7669static PyObject *
7670posix_writev(PyObject *self, PyObject *args)
7671{
7672 int fd, cnt;
7673 Py_ssize_t res;
7674 PyObject *seq;
7675 struct iovec *iov;
7676 Py_buffer *buf;
7677 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7678 return NULL;
7679 if (!PySequence_Check(seq)) {
7680 PyErr_SetString(PyExc_TypeError,
7681 "writev() arg 2 must be a sequence");
7682 return NULL;
7683 }
7684 cnt = PySequence_Size(seq);
7685
7686 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7687 return NULL;
7688 }
7689
7690 Py_BEGIN_ALLOW_THREADS
7691 res = writev(fd, iov, cnt);
7692 Py_END_ALLOW_THREADS
7693
7694 iov_cleanup(iov, buf, cnt);
7695 return PyLong_FromSsize_t(res);
7696}
7697#endif
7698
7699#ifdef HAVE_PWRITE
7700PyDoc_STRVAR(posix_pwrite__doc__,
7701"pwrite(fd, string, offset) -> byteswritten\n\n\
7702Write string to a file descriptor, fd, from offset, leaving the file\n\
7703offset unchanged.");
7704
7705static PyObject *
7706posix_pwrite(PyObject *self, PyObject *args)
7707{
7708 Py_buffer pbuf;
7709 int fd;
7710 off_t offset;
7711 Py_ssize_t size;
7712
7713 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7714 return NULL;
7715
7716 if (!_PyVerify_fd(fd)) {
7717 PyBuffer_Release(&pbuf);
7718 return posix_error();
7719 }
7720 Py_BEGIN_ALLOW_THREADS
7721 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7722 Py_END_ALLOW_THREADS
7723 PyBuffer_Release(&pbuf);
7724 if (size < 0)
7725 return posix_error();
7726 return PyLong_FromSsize_t(size);
7727}
7728#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007729
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007730#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007731PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007732"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
7733Create a FIFO (a POSIX named pipe).\n\
7734\n\
7735If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7736 and path should be relative; path will then be relative to that directory.\n\
7737dir_fd may not be implemented on your platform.\n\
7738 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007739
Barry Warsaw53699e91996-12-10 23:23:01 +00007740static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007741posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007742{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007743 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00007744 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007745 int dir_fd = DEFAULT_DIR_FD;
7746 int result;
7747 PyObject *return_value = NULL;
7748 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
7749
7750 memset(&path, 0, sizeof(path));
7751 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
7752 path_converter, &path,
7753 &mode,
7754#ifdef HAVE_MKFIFOAT
7755 dir_fd_converter, &dir_fd
7756#else
7757 dir_fd_unavailable, &dir_fd
7758#endif
7759 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007761
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007763#ifdef HAVE_MKFIFOAT
7764 if (dir_fd != DEFAULT_DIR_FD)
7765 result = mkfifoat(dir_fd, path.narrow, mode);
7766 else
7767#endif
7768 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007770
7771 if (result < 0) {
7772 return_value = posix_error();
7773 goto exit;
7774 }
7775
7776 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007778
7779exit:
7780 path_cleanup(&path);
7781 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007782}
7783#endif
7784
Neal Norwitz11690112002-07-30 01:08:28 +00007785#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007786PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007787"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007788Create a filesystem node (file, device special file or named pipe)\n\
7789named filename. mode specifies both the permissions to use and the\n\
7790type of node to be created, being combined (bitwise OR) with one of\n\
7791S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007792device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007793os.makedev()), otherwise it is ignored.\n\
7794\n\
7795If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7796 and path should be relative; path will then be relative to that directory.\n\
7797dir_fd may not be implemented on your platform.\n\
7798 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007799
7800
7801static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007802posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007803{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007804 path_t path;
7805 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00007806 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007807 int dir_fd = DEFAULT_DIR_FD;
7808 int result;
7809 PyObject *return_value = NULL;
7810 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
7811
7812 memset(&path, 0, sizeof(path));
7813 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
7814 path_converter, &path,
7815 &mode, &device,
7816#ifdef HAVE_MKNODAT
7817 dir_fd_converter, &dir_fd
7818#else
7819 dir_fd_unavailable, &dir_fd
7820#endif
7821 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007823
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007825#ifdef HAVE_MKNODAT
7826 if (dir_fd != DEFAULT_DIR_FD)
7827 result = mknodat(dir_fd, path.narrow, mode, device);
7828 else
7829#endif
7830 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00007831 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007832
7833 if (result < 0) {
7834 return_value = posix_error();
7835 goto exit;
7836 }
7837
7838 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02007840
Larry Hastings9cf065c2012-06-22 16:30:09 -07007841exit:
7842 path_cleanup(&path);
7843 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007844}
7845#endif
7846
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007847#ifdef HAVE_DEVICE_MACROS
7848PyDoc_STRVAR(posix_major__doc__,
7849"major(device) -> major number\n\
7850Extracts a device major number from a raw device number.");
7851
7852static PyObject *
7853posix_major(PyObject *self, PyObject *args)
7854{
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 int device;
7856 if (!PyArg_ParseTuple(args, "i:major", &device))
7857 return NULL;
7858 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007859}
7860
7861PyDoc_STRVAR(posix_minor__doc__,
7862"minor(device) -> minor number\n\
7863Extracts a device minor number from a raw device number.");
7864
7865static PyObject *
7866posix_minor(PyObject *self, PyObject *args)
7867{
Victor Stinner8c62be82010-05-06 00:08:46 +00007868 int device;
7869 if (!PyArg_ParseTuple(args, "i:minor", &device))
7870 return NULL;
7871 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007872}
7873
7874PyDoc_STRVAR(posix_makedev__doc__,
7875"makedev(major, minor) -> device number\n\
7876Composes a raw device number from the major and minor device numbers.");
7877
7878static PyObject *
7879posix_makedev(PyObject *self, PyObject *args)
7880{
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 int major, minor;
7882 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7883 return NULL;
7884 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007885}
7886#endif /* device macros */
7887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007888
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007889#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007890PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007891"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007892Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007893
Barry Warsaw53699e91996-12-10 23:23:01 +00007894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007895posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007896{
Victor Stinner8c62be82010-05-06 00:08:46 +00007897 int fd;
7898 off_t length;
7899 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007900
Ross Lagerwall7807c352011-03-17 20:20:30 +02007901 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007902 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007903
Victor Stinner8c62be82010-05-06 00:08:46 +00007904 Py_BEGIN_ALLOW_THREADS
7905 res = ftruncate(fd, length);
7906 Py_END_ALLOW_THREADS
7907 if (res < 0)
7908 return posix_error();
7909 Py_INCREF(Py_None);
7910 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007911}
7912#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007913
Ross Lagerwall7807c352011-03-17 20:20:30 +02007914#ifdef HAVE_TRUNCATE
7915PyDoc_STRVAR(posix_truncate__doc__,
7916"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02007917Truncate the file given by path to length bytes.\n\
7918On some platforms, path may also be specified as an open file descriptor.\n\
7919 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02007920
7921static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02007922posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02007923{
Georg Brandl306336b2012-06-24 12:55:33 +02007924 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007925 off_t length;
7926 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02007927 PyObject *result = NULL;
7928 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02007929
Georg Brandl306336b2012-06-24 12:55:33 +02007930 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007931 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02007932#ifdef HAVE_FTRUNCATE
7933 path.allow_fd = 1;
7934#endif
7935 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
7936 path_converter, &path,
7937 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02007938 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007939
7940 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02007941#ifdef HAVE_FTRUNCATE
7942 if (path.fd != -1)
7943 res = ftruncate(path.fd, length);
7944 else
7945#endif
7946 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007947 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02007948 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01007949 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02007950 else {
7951 Py_INCREF(Py_None);
7952 result = Py_None;
7953 }
7954 path_cleanup(&path);
7955 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007956}
7957#endif
7958
7959#ifdef HAVE_POSIX_FALLOCATE
7960PyDoc_STRVAR(posix_posix_fallocate__doc__,
7961"posix_fallocate(fd, offset, len)\n\n\
7962Ensures that enough disk space is allocated for the file specified by fd\n\
7963starting from offset and continuing for len bytes.");
7964
7965static PyObject *
7966posix_posix_fallocate(PyObject *self, PyObject *args)
7967{
7968 off_t len, offset;
7969 int res, fd;
7970
7971 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7972 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7973 return NULL;
7974
7975 Py_BEGIN_ALLOW_THREADS
7976 res = posix_fallocate(fd, offset, len);
7977 Py_END_ALLOW_THREADS
7978 if (res != 0) {
7979 errno = res;
7980 return posix_error();
7981 }
7982 Py_RETURN_NONE;
7983}
7984#endif
7985
7986#ifdef HAVE_POSIX_FADVISE
7987PyDoc_STRVAR(posix_posix_fadvise__doc__,
7988"posix_fadvise(fd, offset, len, advice)\n\n\
7989Announces an intention to access data in a specific pattern thus allowing\n\
7990the kernel to make optimizations.\n\
7991The advice applies to the region of the file specified by fd starting at\n\
7992offset and continuing for len bytes.\n\
7993advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7994POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7995POSIX_FADV_DONTNEED.");
7996
7997static PyObject *
7998posix_posix_fadvise(PyObject *self, PyObject *args)
7999{
8000 off_t len, offset;
8001 int res, fd, advice;
8002
8003 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8004 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8005 return NULL;
8006
8007 Py_BEGIN_ALLOW_THREADS
8008 res = posix_fadvise(fd, offset, len, advice);
8009 Py_END_ALLOW_THREADS
8010 if (res != 0) {
8011 errno = res;
8012 return posix_error();
8013 }
8014 Py_RETURN_NONE;
8015}
8016#endif
8017
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008018#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008019PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008020"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008021Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008022
Fred Drake762e2061999-08-26 17:23:54 +00008023/* Save putenv() parameters as values here, so we can collect them when they
8024 * get re-set with another call for the same key. */
8025static PyObject *posix_putenv_garbage;
8026
Tim Peters5aa91602002-01-30 05:46:57 +00008027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008028posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008029{
Victor Stinner84ae1182010-05-06 22:05:07 +00008030 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008031#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008032 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008033 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008034
Victor Stinner8c62be82010-05-06 00:08:46 +00008035 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008036 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008037 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008038 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008039
Victor Stinner65170952011-11-22 22:16:17 +01008040 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008041 if (newstr == NULL) {
8042 PyErr_NoMemory();
8043 goto error;
8044 }
Victor Stinner65170952011-11-22 22:16:17 +01008045 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8046 PyErr_Format(PyExc_ValueError,
8047 "the environment variable is longer than %u characters",
8048 _MAX_ENV);
8049 goto error;
8050 }
8051
Victor Stinner8c62be82010-05-06 00:08:46 +00008052 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008053 if (newenv == NULL)
8054 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008055 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008056 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008057 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008059#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008060 PyObject *os1, *os2;
8061 char *s1, *s2;
8062 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008063
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008064 if (!PyArg_ParseTuple(args,
8065 "O&O&:putenv",
8066 PyUnicode_FSConverter, &os1,
8067 PyUnicode_FSConverter, &os2))
8068 return NULL;
8069 s1 = PyBytes_AsString(os1);
8070 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008071
Victor Stinner65170952011-11-22 22:16:17 +01008072 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008073 if (newstr == NULL) {
8074 PyErr_NoMemory();
8075 goto error;
8076 }
8077
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008079 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008080 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008081 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008082 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008083#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008084
Victor Stinner8c62be82010-05-06 00:08:46 +00008085 /* Install the first arg and newstr in posix_putenv_garbage;
8086 * this will cause previous value to be collected. This has to
8087 * happen after the real putenv() call because the old value
8088 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008089 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008090 /* really not much we can do; just leak */
8091 PyErr_Clear();
8092 }
8093 else {
8094 Py_DECREF(newstr);
8095 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008096
Martin v. Löwis011e8422009-05-05 04:43:17 +00008097#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008098 Py_DECREF(os1);
8099 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008100#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008101 Py_RETURN_NONE;
8102
8103error:
8104#ifndef MS_WINDOWS
8105 Py_DECREF(os1);
8106 Py_DECREF(os2);
8107#endif
8108 Py_XDECREF(newstr);
8109 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008110}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008111#endif /* putenv */
8112
Guido van Rossumc524d952001-10-19 01:31:59 +00008113#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008114PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008115"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008116Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008117
8118static PyObject *
8119posix_unsetenv(PyObject *self, PyObject *args)
8120{
Victor Stinner65170952011-11-22 22:16:17 +01008121 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008122#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008123 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008124#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008125
8126 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008127
Victor Stinner65170952011-11-22 22:16:17 +01008128 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008129 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008130
Victor Stinner984890f2011-11-24 13:53:38 +01008131#ifdef HAVE_BROKEN_UNSETENV
8132 unsetenv(PyBytes_AS_STRING(name));
8133#else
Victor Stinner65170952011-11-22 22:16:17 +01008134 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008135 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008136 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008137 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008138 }
Victor Stinner984890f2011-11-24 13:53:38 +01008139#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008140
Victor Stinner8c62be82010-05-06 00:08:46 +00008141 /* Remove the key from posix_putenv_garbage;
8142 * this will cause it to be collected. This has to
8143 * happen after the real unsetenv() call because the
8144 * old value was still accessible until then.
8145 */
Victor Stinner65170952011-11-22 22:16:17 +01008146 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008147 /* really not much we can do; just leak */
8148 PyErr_Clear();
8149 }
Victor Stinner65170952011-11-22 22:16:17 +01008150 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008151 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008152}
8153#endif /* unsetenv */
8154
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008155PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008156"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008157Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008158
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008160posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008161{
Victor Stinner8c62be82010-05-06 00:08:46 +00008162 int code;
8163 char *message;
8164 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8165 return NULL;
8166 message = strerror(code);
8167 if (message == NULL) {
8168 PyErr_SetString(PyExc_ValueError,
8169 "strerror() argument out of range");
8170 return NULL;
8171 }
Victor Stinner1b579672011-12-17 05:47:23 +01008172 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008173}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008174
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008175
Guido van Rossumc9641791998-08-04 15:26:23 +00008176#ifdef HAVE_SYS_WAIT_H
8177
Fred Drake106c1a02002-04-23 15:58:02 +00008178#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008179PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008180"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008181Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008182
8183static PyObject *
8184posix_WCOREDUMP(PyObject *self, PyObject *args)
8185{
Victor Stinner8c62be82010-05-06 00:08:46 +00008186 WAIT_TYPE status;
8187 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008188
Victor Stinner8c62be82010-05-06 00:08:46 +00008189 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8190 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008191
Victor Stinner8c62be82010-05-06 00:08:46 +00008192 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008193}
8194#endif /* WCOREDUMP */
8195
8196#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008197PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008198"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008199Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008200job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008201
8202static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008203posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008204{
Victor Stinner8c62be82010-05-06 00:08:46 +00008205 WAIT_TYPE status;
8206 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008207
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8209 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008210
Victor Stinner8c62be82010-05-06 00:08:46 +00008211 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008212}
8213#endif /* WIFCONTINUED */
8214
Guido van Rossumc9641791998-08-04 15:26:23 +00008215#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008216PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008217"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008218Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008219
8220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008221posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008222{
Victor Stinner8c62be82010-05-06 00:08:46 +00008223 WAIT_TYPE status;
8224 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008225
Victor Stinner8c62be82010-05-06 00:08:46 +00008226 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8227 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008228
Victor Stinner8c62be82010-05-06 00:08:46 +00008229 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008230}
8231#endif /* WIFSTOPPED */
8232
8233#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008234PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008235"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008236Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008237
8238static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008239posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008240{
Victor Stinner8c62be82010-05-06 00:08:46 +00008241 WAIT_TYPE status;
8242 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008243
Victor Stinner8c62be82010-05-06 00:08:46 +00008244 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8245 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008246
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008248}
8249#endif /* WIFSIGNALED */
8250
8251#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008252PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008253"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008254Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008255system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008256
8257static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008258posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008259{
Victor Stinner8c62be82010-05-06 00:08:46 +00008260 WAIT_TYPE status;
8261 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008262
Victor Stinner8c62be82010-05-06 00:08:46 +00008263 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8264 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008265
Victor Stinner8c62be82010-05-06 00:08:46 +00008266 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008267}
8268#endif /* WIFEXITED */
8269
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008270#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008271PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008272"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008273Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008274
8275static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008276posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008277{
Victor Stinner8c62be82010-05-06 00:08:46 +00008278 WAIT_TYPE status;
8279 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008280
Victor Stinner8c62be82010-05-06 00:08:46 +00008281 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8282 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008283
Victor Stinner8c62be82010-05-06 00:08:46 +00008284 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008285}
8286#endif /* WEXITSTATUS */
8287
8288#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008289PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008290"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008291Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008292value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008293
8294static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008295posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008296{
Victor Stinner8c62be82010-05-06 00:08:46 +00008297 WAIT_TYPE status;
8298 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008299
Victor Stinner8c62be82010-05-06 00:08:46 +00008300 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8301 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008302
Victor Stinner8c62be82010-05-06 00:08:46 +00008303 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008304}
8305#endif /* WTERMSIG */
8306
8307#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008308PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008309"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008310Return the signal that stopped the process that provided\n\
8311the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008312
8313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008314posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008315{
Victor Stinner8c62be82010-05-06 00:08:46 +00008316 WAIT_TYPE status;
8317 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008318
Victor Stinner8c62be82010-05-06 00:08:46 +00008319 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8320 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008321
Victor Stinner8c62be82010-05-06 00:08:46 +00008322 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008323}
8324#endif /* WSTOPSIG */
8325
8326#endif /* HAVE_SYS_WAIT_H */
8327
8328
Thomas Wouters477c8d52006-05-27 19:21:47 +00008329#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008330#ifdef _SCO_DS
8331/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8332 needed definitions in sys/statvfs.h */
8333#define _SVID3
8334#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008335#include <sys/statvfs.h>
8336
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008337static PyObject*
8338_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008339 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8340 if (v == NULL)
8341 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008342
8343#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008344 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8345 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8346 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8347 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8348 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8349 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8350 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8351 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8352 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8353 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008354#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008355 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8356 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8357 PyStructSequence_SET_ITEM(v, 2,
8358 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8359 PyStructSequence_SET_ITEM(v, 3,
8360 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8361 PyStructSequence_SET_ITEM(v, 4,
8362 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8363 PyStructSequence_SET_ITEM(v, 5,
8364 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8365 PyStructSequence_SET_ITEM(v, 6,
8366 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8367 PyStructSequence_SET_ITEM(v, 7,
8368 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8369 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8370 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008371#endif
8372
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008374}
8375
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008376PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008377"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008378Perform an fstatvfs system call on the given fd.\n\
8379Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008380
8381static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008382posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008383{
Victor Stinner8c62be82010-05-06 00:08:46 +00008384 int fd, res;
8385 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008386
Victor Stinner8c62be82010-05-06 00:08:46 +00008387 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8388 return NULL;
8389 Py_BEGIN_ALLOW_THREADS
8390 res = fstatvfs(fd, &st);
8391 Py_END_ALLOW_THREADS
8392 if (res != 0)
8393 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008394
Victor Stinner8c62be82010-05-06 00:08:46 +00008395 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008396}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008397#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008398
8399
Thomas Wouters477c8d52006-05-27 19:21:47 +00008400#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008401#include <sys/statvfs.h>
8402
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008403PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008404"statvfs(path)\n\n\
8405Perform a statvfs system call on the given path.\n\
8406\n\
8407path may always be specified as a string.\n\
8408On some platforms, path may also be specified as an open file descriptor.\n\
8409 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008410
8411static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008412posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008413{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008414 static char *keywords[] = {"path", NULL};
8415 path_t path;
8416 int result;
8417 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008419
Larry Hastings9cf065c2012-06-22 16:30:09 -07008420 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008421 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07008422#ifdef HAVE_FSTATVFS
8423 path.allow_fd = 1;
8424#endif
8425 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8426 path_converter, &path
8427 ))
8428 return NULL;
8429
8430 Py_BEGIN_ALLOW_THREADS
8431#ifdef HAVE_FSTATVFS
8432 if (path.fd != -1) {
8433#ifdef __APPLE__
8434 /* handle weak-linking on Mac OS X 10.3 */
8435 if (fstatvfs == NULL) {
8436 fd_specified("statvfs", path.fd);
8437 goto exit;
8438 }
8439#endif
8440 result = fstatvfs(path.fd, &st);
8441 }
8442 else
8443#endif
8444 result = statvfs(path.narrow, &st);
8445 Py_END_ALLOW_THREADS
8446
8447 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01008448 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008449 goto exit;
8450 }
8451
8452 return_value = _pystatvfs_fromstructstatvfs(st);
8453
8454exit:
8455 path_cleanup(&path);
8456 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008457}
8458#endif /* HAVE_STATVFS */
8459
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008460#ifdef MS_WINDOWS
8461PyDoc_STRVAR(win32__getdiskusage__doc__,
8462"_getdiskusage(path) -> (total, free)\n\n\
8463Return disk usage statistics about the given path as (total, free) tuple.");
8464
8465static PyObject *
8466win32__getdiskusage(PyObject *self, PyObject *args)
8467{
8468 BOOL retval;
8469 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008470 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008471
Victor Stinner6139c1b2011-11-09 22:14:14 +01008472 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008473 return NULL;
8474
8475 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008476 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008477 Py_END_ALLOW_THREADS
8478 if (retval == 0)
8479 return PyErr_SetFromWindowsErr(0);
8480
8481 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8482}
8483#endif
8484
8485
Fred Drakec9680921999-12-13 16:37:25 +00008486/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8487 * It maps strings representing configuration variable names to
8488 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008489 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008490 * rarely-used constants. There are three separate tables that use
8491 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008492 *
8493 * This code is always included, even if none of the interfaces that
8494 * need it are included. The #if hackery needed to avoid it would be
8495 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008496 */
8497struct constdef {
8498 char *name;
8499 long value;
8500};
8501
Fred Drake12c6e2d1999-12-14 21:25:03 +00008502static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008503conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008504 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008505{
Christian Heimes217cfd12007-12-02 14:31:20 +00008506 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008507 *valuep = PyLong_AS_LONG(arg);
8508 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008509 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008510 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008511 /* look up the value in the table using a binary search */
8512 size_t lo = 0;
8513 size_t mid;
8514 size_t hi = tablesize;
8515 int cmp;
8516 const char *confname;
8517 if (!PyUnicode_Check(arg)) {
8518 PyErr_SetString(PyExc_TypeError,
8519 "configuration names must be strings or integers");
8520 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008521 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008522 confname = _PyUnicode_AsString(arg);
8523 if (confname == NULL)
8524 return 0;
8525 while (lo < hi) {
8526 mid = (lo + hi) / 2;
8527 cmp = strcmp(confname, table[mid].name);
8528 if (cmp < 0)
8529 hi = mid;
8530 else if (cmp > 0)
8531 lo = mid + 1;
8532 else {
8533 *valuep = table[mid].value;
8534 return 1;
8535 }
8536 }
8537 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8538 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008539 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008540}
8541
8542
8543#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8544static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008545#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008546 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008547#endif
8548#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008549 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008550#endif
Fred Drakec9680921999-12-13 16:37:25 +00008551#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008552 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008553#endif
8554#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008555 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008556#endif
8557#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008558 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008559#endif
8560#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008561 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008562#endif
8563#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008564 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008565#endif
8566#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008567 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008568#endif
8569#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008570 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008571#endif
8572#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008573 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008574#endif
8575#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008576 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008577#endif
8578#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008579 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008580#endif
8581#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008582 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008583#endif
8584#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008585 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008586#endif
8587#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008588 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008589#endif
8590#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008591 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008592#endif
8593#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008594 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008595#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008596#ifdef _PC_ACL_ENABLED
8597 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8598#endif
8599#ifdef _PC_MIN_HOLE_SIZE
8600 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8601#endif
8602#ifdef _PC_ALLOC_SIZE_MIN
8603 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8604#endif
8605#ifdef _PC_REC_INCR_XFER_SIZE
8606 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8607#endif
8608#ifdef _PC_REC_MAX_XFER_SIZE
8609 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8610#endif
8611#ifdef _PC_REC_MIN_XFER_SIZE
8612 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8613#endif
8614#ifdef _PC_REC_XFER_ALIGN
8615 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8616#endif
8617#ifdef _PC_SYMLINK_MAX
8618 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8619#endif
8620#ifdef _PC_XATTR_ENABLED
8621 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8622#endif
8623#ifdef _PC_XATTR_EXISTS
8624 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8625#endif
8626#ifdef _PC_TIMESTAMP_RESOLUTION
8627 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8628#endif
Fred Drakec9680921999-12-13 16:37:25 +00008629};
8630
Fred Drakec9680921999-12-13 16:37:25 +00008631static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008632conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008633{
8634 return conv_confname(arg, valuep, posix_constants_pathconf,
8635 sizeof(posix_constants_pathconf)
8636 / sizeof(struct constdef));
8637}
8638#endif
8639
8640#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008641PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008642"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008643Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008644If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008645
8646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008647posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008648{
8649 PyObject *result = NULL;
8650 int name, fd;
8651
Fred Drake12c6e2d1999-12-14 21:25:03 +00008652 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8653 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008654 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008655
Stefan Krah0e803b32010-11-26 16:16:47 +00008656 errno = 0;
8657 limit = fpathconf(fd, name);
8658 if (limit == -1 && errno != 0)
8659 posix_error();
8660 else
8661 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008662 }
8663 return result;
8664}
8665#endif
8666
8667
8668#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008669PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008670"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008671Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008672If there is no limit, return -1.\n\
8673On some platforms, path may also be specified as an open file descriptor.\n\
8674 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00008675
8676static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008677posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00008678{
Georg Brandl306336b2012-06-24 12:55:33 +02008679 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00008680 PyObject *result = NULL;
8681 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02008682 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00008683
Georg Brandl306336b2012-06-24 12:55:33 +02008684 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008685 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02008686#ifdef HAVE_FPATHCONF
8687 path.allow_fd = 1;
8688#endif
8689 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
8690 path_converter, &path,
8691 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008692 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008693
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02008695#ifdef HAVE_FPATHCONF
8696 if (path.fd != -1)
8697 limit = fpathconf(path.fd, name);
8698 else
8699#endif
8700 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00008701 if (limit == -1 && errno != 0) {
8702 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008703 /* could be a path or name problem */
8704 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008705 else
Victor Stinner292c8352012-10-30 02:17:38 +01008706 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008707 }
8708 else
8709 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008710 }
Georg Brandl306336b2012-06-24 12:55:33 +02008711 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00008712 return result;
8713}
8714#endif
8715
8716#ifdef HAVE_CONFSTR
8717static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008718#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008719 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008720#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008721#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008722 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008723#endif
8724#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008725 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008726#endif
Fred Draked86ed291999-12-15 15:34:33 +00008727#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008728 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008729#endif
8730#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008731 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008732#endif
8733#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008734 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008735#endif
8736#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008737 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008738#endif
Fred Drakec9680921999-12-13 16:37:25 +00008739#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008740 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008741#endif
8742#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008743 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008744#endif
8745#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008746 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008747#endif
8748#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008749 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008750#endif
8751#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008752 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008753#endif
8754#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008755 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008756#endif
8757#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008758 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008759#endif
8760#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008761 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008762#endif
Fred Draked86ed291999-12-15 15:34:33 +00008763#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008764 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008765#endif
Fred Drakec9680921999-12-13 16:37:25 +00008766#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008767 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008768#endif
Fred Draked86ed291999-12-15 15:34:33 +00008769#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008770 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008771#endif
8772#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008773 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008774#endif
8775#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008776 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008777#endif
8778#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008779 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008780#endif
Fred Drakec9680921999-12-13 16:37:25 +00008781#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008782 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008783#endif
8784#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008785 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008786#endif
8787#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008788 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008789#endif
8790#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008791 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008792#endif
8793#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008794 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008795#endif
8796#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008797 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008798#endif
8799#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008800 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008801#endif
8802#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008803 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008804#endif
8805#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008806 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008807#endif
8808#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008809 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008810#endif
8811#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008812 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008813#endif
8814#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008815 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008816#endif
8817#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008818 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008819#endif
8820#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008821 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008822#endif
8823#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008824 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008825#endif
8826#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008827 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008828#endif
Fred Draked86ed291999-12-15 15:34:33 +00008829#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008830 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008831#endif
8832#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008833 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008834#endif
8835#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008836 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008837#endif
8838#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008839 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008840#endif
8841#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008842 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008843#endif
8844#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008845 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008846#endif
8847#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008848 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008849#endif
8850#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008851 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008852#endif
8853#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008854 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008855#endif
8856#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008857 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008858#endif
8859#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008860 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008861#endif
8862#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008863 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008864#endif
8865#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008866 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008867#endif
Fred Drakec9680921999-12-13 16:37:25 +00008868};
8869
8870static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008871conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008872{
8873 return conv_confname(arg, valuep, posix_constants_confstr,
8874 sizeof(posix_constants_confstr)
8875 / sizeof(struct constdef));
8876}
8877
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008878PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008879"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008880Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008881
8882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008883posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008884{
8885 PyObject *result = NULL;
8886 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008887 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008888 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008889
Victor Stinnercb043522010-09-10 23:49:04 +00008890 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8891 return NULL;
8892
8893 errno = 0;
8894 len = confstr(name, buffer, sizeof(buffer));
8895 if (len == 0) {
8896 if (errno) {
8897 posix_error();
8898 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008899 }
8900 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008901 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008902 }
8903 }
Victor Stinnercb043522010-09-10 23:49:04 +00008904
8905 if ((unsigned int)len >= sizeof(buffer)) {
8906 char *buf = PyMem_Malloc(len);
8907 if (buf == NULL)
8908 return PyErr_NoMemory();
8909 confstr(name, buf, len);
8910 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8911 PyMem_Free(buf);
8912 }
8913 else
8914 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008915 return result;
8916}
8917#endif
8918
8919
8920#ifdef HAVE_SYSCONF
8921static struct constdef posix_constants_sysconf[] = {
8922#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008923 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008924#endif
8925#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008926 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008927#endif
8928#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008929 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008930#endif
8931#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008932 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008933#endif
8934#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008936#endif
8937#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008938 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008939#endif
8940#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008941 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008942#endif
8943#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008944 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008945#endif
8946#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008947 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008948#endif
8949#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008950 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008951#endif
Fred Draked86ed291999-12-15 15:34:33 +00008952#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008953 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008954#endif
8955#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008956 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008957#endif
Fred Drakec9680921999-12-13 16:37:25 +00008958#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008959 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008960#endif
Fred Drakec9680921999-12-13 16:37:25 +00008961#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008962 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008963#endif
8964#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008965 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008966#endif
8967#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008968 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008969#endif
8970#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008971 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008972#endif
8973#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008974 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008975#endif
Fred Draked86ed291999-12-15 15:34:33 +00008976#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008977 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008978#endif
Fred Drakec9680921999-12-13 16:37:25 +00008979#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008980 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008981#endif
8982#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008983 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008984#endif
8985#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008986 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008987#endif
8988#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008989 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008990#endif
8991#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008992 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008993#endif
Fred Draked86ed291999-12-15 15:34:33 +00008994#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008996#endif
Fred Drakec9680921999-12-13 16:37:25 +00008997#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008999#endif
9000#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009001 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009002#endif
9003#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009005#endif
9006#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009007 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009008#endif
9009#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009010 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009011#endif
9012#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009014#endif
9015#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009016 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009017#endif
9018#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009019 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009020#endif
9021#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009022 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009023#endif
9024#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009025 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009026#endif
9027#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009029#endif
9030#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009031 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009032#endif
9033#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009034 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009035#endif
9036#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009037 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009038#endif
9039#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009041#endif
9042#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009043 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009044#endif
9045#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009046 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009047#endif
9048#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009049 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009050#endif
9051#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009052 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009053#endif
9054#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009055 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009056#endif
9057#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009058 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009059#endif
9060#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009061 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009062#endif
9063#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009064 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009065#endif
Fred Draked86ed291999-12-15 15:34:33 +00009066#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009067 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009068#endif
Fred Drakec9680921999-12-13 16:37:25 +00009069#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009070 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009071#endif
9072#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009073 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009074#endif
9075#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009076 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009077#endif
Fred Draked86ed291999-12-15 15:34:33 +00009078#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009079 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009080#endif
Fred Drakec9680921999-12-13 16:37:25 +00009081#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009082 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009083#endif
Fred Draked86ed291999-12-15 15:34:33 +00009084#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009086#endif
9087#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009089#endif
Fred Drakec9680921999-12-13 16:37:25 +00009090#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009092#endif
9093#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009094 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009095#endif
9096#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009097 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009098#endif
9099#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009100 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009101#endif
Fred Draked86ed291999-12-15 15:34:33 +00009102#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009103 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009104#endif
Fred Drakec9680921999-12-13 16:37:25 +00009105#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009106 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009107#endif
9108#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009109 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009110#endif
9111#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009112 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009113#endif
9114#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009115 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009116#endif
9117#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009118 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009119#endif
9120#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009121 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009122#endif
9123#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009125#endif
Fred Draked86ed291999-12-15 15:34:33 +00009126#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009127 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009128#endif
Fred Drakec9680921999-12-13 16:37:25 +00009129#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009130 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009131#endif
9132#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009133 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009134#endif
Fred Draked86ed291999-12-15 15:34:33 +00009135#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009136 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009137#endif
Fred Drakec9680921999-12-13 16:37:25 +00009138#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009139 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009140#endif
9141#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009142 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009143#endif
9144#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009145 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009146#endif
9147#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009148 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009149#endif
9150#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009151 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009152#endif
9153#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009154 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009155#endif
9156#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009157 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009158#endif
9159#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009161#endif
9162#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009163 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009164#endif
Fred Draked86ed291999-12-15 15:34:33 +00009165#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009166 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009167#endif
9168#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009169 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009170#endif
Fred Drakec9680921999-12-13 16:37:25 +00009171#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009172 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009173#endif
9174#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009175 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009176#endif
9177#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009178 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009179#endif
9180#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009181 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009182#endif
9183#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009184 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009185#endif
9186#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009187 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009188#endif
9189#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009190 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009191#endif
9192#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009193 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009194#endif
9195#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009196 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009197#endif
9198#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009199 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009200#endif
9201#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009202 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009203#endif
9204#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009205 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009206#endif
9207#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009208 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009209#endif
9210#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009211 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009212#endif
9213#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009214 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009215#endif
9216#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009217 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009218#endif
9219#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009220 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009221#endif
9222#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009223 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009224#endif
9225#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009226 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009227#endif
9228#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009229 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009230#endif
9231#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009232 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009233#endif
9234#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009235 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009236#endif
9237#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009238 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009239#endif
9240#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009241 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009242#endif
9243#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009244 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009245#endif
9246#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009247 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009248#endif
9249#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009250 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009251#endif
9252#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009253 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009254#endif
9255#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009256 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009257#endif
9258#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009259 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009260#endif
9261#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009262 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009263#endif
9264#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009265 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009266#endif
9267#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009268 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009269#endif
9270#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009271 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009272#endif
9273#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009274 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009275#endif
Fred Draked86ed291999-12-15 15:34:33 +00009276#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009277 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009278#endif
Fred Drakec9680921999-12-13 16:37:25 +00009279#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009280 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009281#endif
9282#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009283 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009284#endif
9285#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009286 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009287#endif
9288#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009289 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009290#endif
9291#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009292 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009293#endif
9294#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009296#endif
9297#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009298 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009299#endif
9300#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009301 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009302#endif
9303#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009304 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009305#endif
9306#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009307 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009308#endif
9309#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009310 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009311#endif
9312#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009313 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009314#endif
9315#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009317#endif
9318#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009319 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009320#endif
9321#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009323#endif
9324#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009326#endif
9327#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009328 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009329#endif
9330#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009332#endif
9333#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009334 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009335#endif
9336#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009337 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009338#endif
9339#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009340 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009341#endif
9342#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009344#endif
9345#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009347#endif
9348#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009350#endif
9351#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009353#endif
9354#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009356#endif
9357#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009359#endif
9360#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009362#endif
9363#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009365#endif
9366#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009368#endif
9369#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009371#endif
9372#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009374#endif
9375#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009377#endif
9378#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
9381#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009383#endif
9384#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009386#endif
9387#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009389#endif
9390#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
9393#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
9399#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009401#endif
9402#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009404#endif
9405#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009407#endif
9408#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009409 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009410#endif
9411#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009413#endif
9414};
9415
9416static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009417conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009418{
9419 return conv_confname(arg, valuep, posix_constants_sysconf,
9420 sizeof(posix_constants_sysconf)
9421 / sizeof(struct constdef));
9422}
9423
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009424PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009425"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009426Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009427
9428static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009429posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009430{
9431 PyObject *result = NULL;
9432 int name;
9433
9434 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9435 int value;
9436
9437 errno = 0;
9438 value = sysconf(name);
9439 if (value == -1 && errno != 0)
9440 posix_error();
9441 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009442 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009443 }
9444 return result;
9445}
9446#endif
9447
9448
Fred Drakebec628d1999-12-15 18:31:10 +00009449/* This code is used to ensure that the tables of configuration value names
9450 * are in sorted order as required by conv_confname(), and also to build the
9451 * the exported dictionaries that are used to publish information about the
9452 * names available on the host platform.
9453 *
9454 * Sorting the table at runtime ensures that the table is properly ordered
9455 * when used, even for platforms we're not able to test on. It also makes
9456 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009457 */
Fred Drakebec628d1999-12-15 18:31:10 +00009458
9459static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009460cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009461{
9462 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009464 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009466
9467 return strcmp(c1->name, c2->name);
9468}
9469
9470static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009471setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009473{
Fred Drakebec628d1999-12-15 18:31:10 +00009474 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009475 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009476
9477 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9478 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009479 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009480 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009481
Barry Warsaw3155db32000-04-13 15:20:40 +00009482 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009483 PyObject *o = PyLong_FromLong(table[i].value);
9484 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9485 Py_XDECREF(o);
9486 Py_DECREF(d);
9487 return -1;
9488 }
9489 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009490 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009491 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009492}
9493
Fred Drakebec628d1999-12-15 18:31:10 +00009494/* Return -1 on failure, 0 on success. */
9495static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009496setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009497{
9498#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009499 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009500 sizeof(posix_constants_pathconf)
9501 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009502 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009503 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009504#endif
9505#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009506 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009507 sizeof(posix_constants_confstr)
9508 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009509 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009510 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009511#endif
9512#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009513 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009514 sizeof(posix_constants_sysconf)
9515 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009516 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009517 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009518#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009519 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009520}
Fred Draked86ed291999-12-15 15:34:33 +00009521
9522
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009523PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009524"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009525Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009526in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009527
9528static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009529posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009530{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009531 abort();
9532 /*NOTREACHED*/
9533 Py_FatalError("abort() called from Python code didn't abort!");
9534 return NULL;
9535}
Fred Drakebec628d1999-12-15 18:31:10 +00009536
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009537#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009538PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009539"startfile(filepath [, operation]) - Start a file with its associated\n\
9540application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009541\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009542When \"operation\" is not specified or \"open\", this acts like\n\
9543double-clicking the file in Explorer, or giving the file name as an\n\
9544argument to the DOS \"start\" command: the file is opened with whatever\n\
9545application (if any) its extension is associated.\n\
9546When another \"operation\" is given, it specifies what should be done with\n\
9547the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009548\n\
9549startfile returns as soon as the associated application is launched.\n\
9550There is no option to wait for the application to close, and no way\n\
9551to retrieve the application's exit status.\n\
9552\n\
9553The filepath is relative to the current directory. If you want to use\n\
9554an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009555the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009556
9557static PyObject *
9558win32_startfile(PyObject *self, PyObject *args)
9559{
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 PyObject *ofilepath;
9561 char *filepath;
9562 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009563 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009565
Victor Stinnereb5657a2011-09-30 01:44:27 +02009566 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 if (!PyArg_ParseTuple(args, "U|s:startfile",
9568 &unipath, &operation)) {
9569 PyErr_Clear();
9570 goto normal;
9571 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009572
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009574 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009576 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 PyErr_Clear();
9578 operation = NULL;
9579 goto normal;
9580 }
9581 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009582
Victor Stinnereb5657a2011-09-30 01:44:27 +02009583 wpath = PyUnicode_AsUnicode(unipath);
9584 if (wpath == NULL)
9585 goto normal;
9586 if (uoperation) {
9587 woperation = PyUnicode_AsUnicode(uoperation);
9588 if (woperation == NULL)
9589 goto normal;
9590 }
9591 else
9592 woperation = NULL;
9593
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009595 rc = ShellExecuteW((HWND)0, woperation, wpath,
9596 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 Py_END_ALLOW_THREADS
9598
Victor Stinnereb5657a2011-09-30 01:44:27 +02009599 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009601 win32_error_object("startfile", unipath);
9602 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 }
9604 Py_INCREF(Py_None);
9605 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009606
9607normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9609 PyUnicode_FSConverter, &ofilepath,
9610 &operation))
9611 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009612 if (win32_warn_bytes_api()) {
9613 Py_DECREF(ofilepath);
9614 return NULL;
9615 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 filepath = PyBytes_AsString(ofilepath);
9617 Py_BEGIN_ALLOW_THREADS
9618 rc = ShellExecute((HWND)0, operation, filepath,
9619 NULL, NULL, SW_SHOWNORMAL);
9620 Py_END_ALLOW_THREADS
9621 if (rc <= (HINSTANCE)32) {
9622 PyObject *errval = win32_error("startfile", filepath);
9623 Py_DECREF(ofilepath);
9624 return errval;
9625 }
9626 Py_DECREF(ofilepath);
9627 Py_INCREF(Py_None);
9628 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009629}
9630#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009631
Martin v. Löwis438b5342002-12-27 10:16:42 +00009632#ifdef HAVE_GETLOADAVG
9633PyDoc_STRVAR(posix_getloadavg__doc__,
9634"getloadavg() -> (float, float, float)\n\n\
9635Return the number of processes in the system run queue averaged over\n\
9636the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9637was unobtainable");
9638
9639static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009640posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009641{
9642 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009643 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009644 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9645 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009646 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009647 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009648}
9649#endif
9650
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009651PyDoc_STRVAR(device_encoding__doc__,
9652"device_encoding(fd) -> str\n\n\
9653Return a string describing the encoding of the device\n\
9654if the output is a terminal; else return None.");
9655
9656static PyObject *
9657device_encoding(PyObject *self, PyObject *args)
9658{
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009660
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9662 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009663
9664 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009665}
9666
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009667#ifdef HAVE_SETRESUID
9668PyDoc_STRVAR(posix_setresuid__doc__,
9669"setresuid(ruid, euid, suid)\n\n\
9670Set the current process's real, effective, and saved user ids.");
9671
9672static PyObject*
9673posix_setresuid (PyObject *self, PyObject *args)
9674{
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 /* We assume uid_t is no larger than a long. */
9676 long ruid, euid, suid;
9677 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9678 return NULL;
9679 if (setresuid(ruid, euid, suid) < 0)
9680 return posix_error();
9681 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009682}
9683#endif
9684
9685#ifdef HAVE_SETRESGID
9686PyDoc_STRVAR(posix_setresgid__doc__,
9687"setresgid(rgid, egid, sgid)\n\n\
9688Set the current process's real, effective, and saved group ids.");
9689
9690static PyObject*
9691posix_setresgid (PyObject *self, PyObject *args)
9692{
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 /* We assume uid_t is no larger than a long. */
9694 long rgid, egid, sgid;
9695 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9696 return NULL;
9697 if (setresgid(rgid, egid, sgid) < 0)
9698 return posix_error();
9699 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009700}
9701#endif
9702
9703#ifdef HAVE_GETRESUID
9704PyDoc_STRVAR(posix_getresuid__doc__,
9705"getresuid() -> (ruid, euid, suid)\n\n\
9706Get tuple of the current process's real, effective, and saved user ids.");
9707
9708static PyObject*
9709posix_getresuid (PyObject *self, PyObject *noargs)
9710{
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 uid_t ruid, euid, suid;
9712 long l_ruid, l_euid, l_suid;
9713 if (getresuid(&ruid, &euid, &suid) < 0)
9714 return posix_error();
9715 /* Force the values into long's as we don't know the size of uid_t. */
9716 l_ruid = ruid;
9717 l_euid = euid;
9718 l_suid = suid;
9719 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009720}
9721#endif
9722
9723#ifdef HAVE_GETRESGID
9724PyDoc_STRVAR(posix_getresgid__doc__,
9725"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009726Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009727
9728static PyObject*
9729posix_getresgid (PyObject *self, PyObject *noargs)
9730{
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 uid_t rgid, egid, sgid;
9732 long l_rgid, l_egid, l_sgid;
9733 if (getresgid(&rgid, &egid, &sgid) < 0)
9734 return posix_error();
9735 /* Force the values into long's as we don't know the size of uid_t. */
9736 l_rgid = rgid;
9737 l_egid = egid;
9738 l_sgid = sgid;
9739 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009740}
9741#endif
9742
Benjamin Peterson9428d532011-09-14 11:45:52 -04009743#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -04009744
Benjamin Peterson799bd802011-08-31 22:15:17 -04009745PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009746"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
9747Return the value of extended attribute attribute on path.\n\
9748\n\
9749path may be either a string or an open file descriptor.\n\
9750If follow_symlinks is False, and the last element of the path is a symbolic\n\
9751 link, getxattr will examine the symbolic link itself instead of the file\n\
9752 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009753
9754static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009755posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009756{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009757 path_t path;
9758 path_t attribute;
9759 int follow_symlinks = 1;
9760 PyObject *buffer = NULL;
9761 int i;
9762 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009763
Larry Hastings9cf065c2012-06-22 16:30:09 -07009764 memset(&path, 0, sizeof(path));
9765 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009766 path.function_name = "getxattr";
9767 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009768 path.allow_fd = 1;
9769 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
9770 path_converter, &path,
9771 path_converter, &attribute,
9772 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009773 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009774
Larry Hastings9cf065c2012-06-22 16:30:09 -07009775 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
9776 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009777
Larry Hastings9cf065c2012-06-22 16:30:09 -07009778 for (i = 0; ; i++) {
9779 void *ptr;
9780 ssize_t result;
9781 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
9782 Py_ssize_t buffer_size = buffer_sizes[i];
9783 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +01009784 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009785 goto exit;
9786 }
9787 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
9788 if (!buffer)
9789 goto exit;
9790 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009791
Larry Hastings9cf065c2012-06-22 16:30:09 -07009792 Py_BEGIN_ALLOW_THREADS;
9793 if (path.fd >= 0)
9794 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
9795 else if (follow_symlinks)
9796 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9797 else
9798 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9799 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009800
Larry Hastings9cf065c2012-06-22 16:30:09 -07009801 if (result < 0) {
9802 Py_DECREF(buffer);
9803 buffer = NULL;
9804 if (errno == ERANGE)
9805 continue;
Victor Stinner292c8352012-10-30 02:17:38 +01009806 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009807 goto exit;
9808 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009809
Larry Hastings9cf065c2012-06-22 16:30:09 -07009810 if (result != buffer_size) {
9811 /* Can only shrink. */
9812 _PyBytes_Resize(&buffer, result);
9813 }
9814 break;
9815 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009816
Larry Hastings9cf065c2012-06-22 16:30:09 -07009817exit:
9818 path_cleanup(&path);
9819 path_cleanup(&attribute);
9820 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009821}
9822
9823PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009824"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
9825Set extended attribute attribute on path to value.\n\
9826path may be either a string or an open file descriptor.\n\
9827If follow_symlinks is False, and the last element of the path is a symbolic\n\
9828 link, setxattr will modify the symbolic link itself instead of the file\n\
9829 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009830
9831static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009832posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009833{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009834 path_t path;
9835 path_t attribute;
9836 Py_buffer value;
9837 int flags = 0;
9838 int follow_symlinks = 1;
9839 int result;
9840 PyObject *return_value = NULL;
9841 static char *keywords[] = {"path", "attribute", "value",
9842 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009843
Larry Hastings9cf065c2012-06-22 16:30:09 -07009844 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009845 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009846 path.allow_fd = 1;
9847 memset(&attribute, 0, sizeof(attribute));
9848 memset(&value, 0, sizeof(value));
9849 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
9850 keywords,
9851 path_converter, &path,
9852 path_converter, &attribute,
9853 &value, &flags,
9854 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009855 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009856
9857 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
9858 goto exit;
9859
Benjamin Peterson799bd802011-08-31 22:15:17 -04009860 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009861 if (path.fd > -1)
9862 result = fsetxattr(path.fd, attribute.narrow,
9863 value.buf, value.len, flags);
9864 else if (follow_symlinks)
9865 result = setxattr(path.narrow, attribute.narrow,
9866 value.buf, value.len, flags);
9867 else
9868 result = lsetxattr(path.narrow, attribute.narrow,
9869 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009870 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009871
Larry Hastings9cf065c2012-06-22 16:30:09 -07009872 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009873 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009874 goto exit;
9875 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009876
Larry Hastings9cf065c2012-06-22 16:30:09 -07009877 return_value = Py_None;
9878 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009879
Larry Hastings9cf065c2012-06-22 16:30:09 -07009880exit:
9881 path_cleanup(&path);
9882 path_cleanup(&attribute);
9883 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009884
Larry Hastings9cf065c2012-06-22 16:30:09 -07009885 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009886}
9887
9888PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009889"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
9890Remove extended attribute attribute on path.\n\
9891path may be either a string or an open file descriptor.\n\
9892If follow_symlinks is False, and the last element of the path is a symbolic\n\
9893 link, removexattr will modify the symbolic link itself instead of the file\n\
9894 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009895
9896static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009897posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009898{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009899 path_t path;
9900 path_t attribute;
9901 int follow_symlinks = 1;
9902 int result;
9903 PyObject *return_value = NULL;
9904 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009905
Larry Hastings9cf065c2012-06-22 16:30:09 -07009906 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009907 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009908 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009909 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009910 path.allow_fd = 1;
9911 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
9912 keywords,
9913 path_converter, &path,
9914 path_converter, &attribute,
9915 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009916 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009917
9918 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
9919 goto exit;
9920
Benjamin Peterson799bd802011-08-31 22:15:17 -04009921 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009922 if (path.fd > -1)
9923 result = fremovexattr(path.fd, attribute.narrow);
9924 else if (follow_symlinks)
9925 result = removexattr(path.narrow, attribute.narrow);
9926 else
9927 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009928 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009929
Larry Hastings9cf065c2012-06-22 16:30:09 -07009930 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009931 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009932 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009933 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009934
Larry Hastings9cf065c2012-06-22 16:30:09 -07009935 return_value = Py_None;
9936 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009937
Larry Hastings9cf065c2012-06-22 16:30:09 -07009938exit:
9939 path_cleanup(&path);
9940 path_cleanup(&attribute);
9941
9942 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009943}
9944
9945PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009946"listxattr(path='.', *, follow_symlinks=True)\n\n\
9947Return a list of extended attributes on path.\n\
9948\n\
9949path may be either None, a string, or an open file descriptor.\n\
9950if path is None, listxattr will examine the current directory.\n\
9951If follow_symlinks is False, and the last element of the path is a symbolic\n\
9952 link, listxattr will examine the symbolic link itself instead of the file\n\
9953 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009954
9955static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009956posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009957{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009958 path_t path;
9959 int follow_symlinks = 1;
9960 Py_ssize_t i;
9961 PyObject *result = NULL;
9962 char *buffer = NULL;
9963 char *name;
9964 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009965
Larry Hastings9cf065c2012-06-22 16:30:09 -07009966 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009967 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009968 path.allow_fd = 1;
9969 path.fd = -1;
9970 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
9971 path_converter, &path,
9972 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009973 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009974
Larry Hastings9cf065c2012-06-22 16:30:09 -07009975 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
9976 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009977
Larry Hastings9cf065c2012-06-22 16:30:09 -07009978 name = path.narrow ? path.narrow : ".";
9979 for (i = 0; ; i++) {
9980 char *start, *trace, *end;
9981 ssize_t length;
9982 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
9983 Py_ssize_t buffer_size = buffer_sizes[i];
9984 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +02009985 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +01009986 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009987 break;
9988 }
9989 buffer = PyMem_MALLOC(buffer_size);
9990 if (!buffer) {
9991 PyErr_NoMemory();
9992 break;
9993 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009994
Larry Hastings9cf065c2012-06-22 16:30:09 -07009995 Py_BEGIN_ALLOW_THREADS;
9996 if (path.fd > -1)
9997 length = flistxattr(path.fd, buffer, buffer_size);
9998 else if (follow_symlinks)
9999 length = listxattr(name, buffer, buffer_size);
10000 else
10001 length = llistxattr(name, buffer, buffer_size);
10002 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010003
Larry Hastings9cf065c2012-06-22 16:30:09 -070010004 if (length < 0) {
10005 if (errno == ERANGE)
10006 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010007 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010008 break;
10009 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010010
Larry Hastings9cf065c2012-06-22 16:30:09 -070010011 result = PyList_New(0);
10012 if (!result) {
10013 goto exit;
10014 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010015
Larry Hastings9cf065c2012-06-22 16:30:09 -070010016 end = buffer + length;
10017 for (trace = start = buffer; trace != end; trace++) {
10018 if (!*trace) {
10019 int error;
10020 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10021 trace - start);
10022 if (!attribute) {
10023 Py_DECREF(result);
10024 result = NULL;
10025 goto exit;
10026 }
10027 error = PyList_Append(result, attribute);
10028 Py_DECREF(attribute);
10029 if (error) {
10030 Py_DECREF(result);
10031 result = NULL;
10032 goto exit;
10033 }
10034 start = trace + 1;
10035 }
10036 }
10037 break;
10038 }
10039exit:
10040 path_cleanup(&path);
10041 if (buffer)
10042 PyMem_FREE(buffer);
10043 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010044}
10045
Benjamin Peterson9428d532011-09-14 11:45:52 -040010046#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010047
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010048
Georg Brandl2fb477c2012-02-21 00:33:36 +010010049PyDoc_STRVAR(posix_urandom__doc__,
10050"urandom(n) -> str\n\n\
10051Return n random bytes suitable for cryptographic use.");
10052
10053static PyObject *
10054posix_urandom(PyObject *self, PyObject *args)
10055{
10056 Py_ssize_t size;
10057 PyObject *result;
10058 int ret;
10059
10060 /* Read arguments */
10061 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10062 return NULL;
10063 if (size < 0)
10064 return PyErr_Format(PyExc_ValueError,
10065 "negative argument not allowed");
10066 result = PyBytes_FromStringAndSize(NULL, size);
10067 if (result == NULL)
10068 return NULL;
10069
10070 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10071 PyBytes_GET_SIZE(result));
10072 if (ret == -1) {
10073 Py_DECREF(result);
10074 return NULL;
10075 }
10076 return result;
10077}
10078
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010079/* Terminal size querying */
10080
10081static PyTypeObject TerminalSizeType;
10082
10083PyDoc_STRVAR(TerminalSize_docstring,
10084 "A tuple of (columns, lines) for holding terminal window size");
10085
10086static PyStructSequence_Field TerminalSize_fields[] = {
10087 {"columns", "width of the terminal window in characters"},
10088 {"lines", "height of the terminal window in characters"},
10089 {NULL, NULL}
10090};
10091
10092static PyStructSequence_Desc TerminalSize_desc = {
10093 "os.terminal_size",
10094 TerminalSize_docstring,
10095 TerminalSize_fields,
10096 2,
10097};
10098
10099#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10100PyDoc_STRVAR(termsize__doc__,
10101 "Return the size of the terminal window as (columns, lines).\n" \
10102 "\n" \
10103 "The optional argument fd (default standard output) specifies\n" \
10104 "which file descriptor should be queried.\n" \
10105 "\n" \
10106 "If the file descriptor is not connected to a terminal, an OSError\n" \
10107 "is thrown.\n" \
10108 "\n" \
10109 "This function will only be defined if an implementation is\n" \
10110 "available for this system.\n" \
10111 "\n" \
10112 "shutil.get_terminal_size is the high-level function which should \n" \
10113 "normally be used, os.get_terminal_size is the low-level implementation.");
10114
10115static PyObject*
10116get_terminal_size(PyObject *self, PyObject *args)
10117{
10118 int columns, lines;
10119 PyObject *termsize;
10120
10121 int fd = fileno(stdout);
10122 /* Under some conditions stdout may not be connected and
10123 * fileno(stdout) may point to an invalid file descriptor. For example
10124 * GUI apps don't have valid standard streams by default.
10125 *
10126 * If this happens, and the optional fd argument is not present,
10127 * the ioctl below will fail returning EBADF. This is what we want.
10128 */
10129
10130 if (!PyArg_ParseTuple(args, "|i", &fd))
10131 return NULL;
10132
10133#ifdef TERMSIZE_USE_IOCTL
10134 {
10135 struct winsize w;
10136 if (ioctl(fd, TIOCGWINSZ, &w))
10137 return PyErr_SetFromErrno(PyExc_OSError);
10138 columns = w.ws_col;
10139 lines = w.ws_row;
10140 }
10141#endif /* TERMSIZE_USE_IOCTL */
10142
10143#ifdef TERMSIZE_USE_CONIO
10144 {
10145 DWORD nhandle;
10146 HANDLE handle;
10147 CONSOLE_SCREEN_BUFFER_INFO csbi;
10148 switch (fd) {
10149 case 0: nhandle = STD_INPUT_HANDLE;
10150 break;
10151 case 1: nhandle = STD_OUTPUT_HANDLE;
10152 break;
10153 case 2: nhandle = STD_ERROR_HANDLE;
10154 break;
10155 default:
10156 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10157 }
10158 handle = GetStdHandle(nhandle);
10159 if (handle == NULL)
10160 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10161 if (handle == INVALID_HANDLE_VALUE)
10162 return PyErr_SetFromWindowsErr(0);
10163
10164 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10165 return PyErr_SetFromWindowsErr(0);
10166
10167 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10168 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10169 }
10170#endif /* TERMSIZE_USE_CONIO */
10171
10172 termsize = PyStructSequence_New(&TerminalSizeType);
10173 if (termsize == NULL)
10174 return NULL;
10175 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10176 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10177 if (PyErr_Occurred()) {
10178 Py_DECREF(termsize);
10179 return NULL;
10180 }
10181 return termsize;
10182}
10183#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10184
10185
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010186static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010187 {"access", (PyCFunction)posix_access,
10188 METH_VARARGS | METH_KEYWORDS,
10189 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010190#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010192#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010193 {"chdir", (PyCFunction)posix_chdir,
10194 METH_VARARGS | METH_KEYWORDS,
10195 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010196#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010197 {"chflags", (PyCFunction)posix_chflags,
10198 METH_VARARGS | METH_KEYWORDS,
10199 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010200#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010201 {"chmod", (PyCFunction)posix_chmod,
10202 METH_VARARGS | METH_KEYWORDS,
10203 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010204#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010206#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010207#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010208 {"chown", (PyCFunction)posix_chown,
10209 METH_VARARGS | METH_KEYWORDS,
10210 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010211#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010212#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010214#endif /* HAVE_LCHMOD */
10215#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010217#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010218#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010220#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010221#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010223#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010224#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010226#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010227#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010229#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010230#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10232 METH_NOARGS, posix_getcwd__doc__},
10233 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10234 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010235#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010236#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10237 {"link", (PyCFunction)posix_link,
10238 METH_VARARGS | METH_KEYWORDS,
10239 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010240#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010241 {"listdir", (PyCFunction)posix_listdir,
10242 METH_VARARGS | METH_KEYWORDS,
10243 posix_listdir__doc__},
10244 {"lstat", (PyCFunction)posix_lstat,
10245 METH_VARARGS | METH_KEYWORDS,
10246 posix_lstat__doc__},
10247 {"mkdir", (PyCFunction)posix_mkdir,
10248 METH_VARARGS | METH_KEYWORDS,
10249 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010250#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010252#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010253#ifdef HAVE_GETPRIORITY
10254 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10255#endif /* HAVE_GETPRIORITY */
10256#ifdef HAVE_SETPRIORITY
10257 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10258#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010259#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010260 {"readlink", (PyCFunction)posix_readlink,
10261 METH_VARARGS | METH_KEYWORDS,
10262 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010263#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010264#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010265 {"readlink", (PyCFunction)win_readlink,
10266 METH_VARARGS | METH_KEYWORDS,
10267 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010268#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010269 {"rename", (PyCFunction)posix_rename,
10270 METH_VARARGS | METH_KEYWORDS,
10271 posix_rename__doc__},
10272 {"replace", (PyCFunction)posix_replace,
10273 METH_VARARGS | METH_KEYWORDS,
10274 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010275 {"rmdir", (PyCFunction)posix_rmdir,
10276 METH_VARARGS | METH_KEYWORDS,
10277 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010278 {"stat", (PyCFunction)posix_stat,
10279 METH_VARARGS | METH_KEYWORDS,
10280 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010282#if defined(HAVE_SYMLINK)
10283 {"symlink", (PyCFunction)posix_symlink,
10284 METH_VARARGS | METH_KEYWORDS,
10285 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010286#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010287#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010289#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010291#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010293#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010294 {"unlink", (PyCFunction)posix_unlink,
10295 METH_VARARGS | METH_KEYWORDS,
10296 posix_unlink__doc__},
10297 {"remove", (PyCFunction)posix_unlink,
10298 METH_VARARGS | METH_KEYWORDS,
10299 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010300 {"utime", (PyCFunction)posix_utime,
10301 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010302#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010304#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010306#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010308 {"execve", (PyCFunction)posix_execve,
10309 METH_VARARGS | METH_KEYWORDS,
10310 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010311#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010312#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10314 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000010315#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010316#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010318#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010319#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010321#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010322#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010323#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010324 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10325 {"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 +020010326#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010327#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010328 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010329#endif
10330#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010331 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010332#endif
10333#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010334 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010335#endif
10336#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010337 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010338#endif
10339#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010340 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010341#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010342 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010343#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010344 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10345 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10346#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010347#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010348#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010350#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010351#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010353#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010354#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010356#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010357#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010359#endif /* HAVE_GETEUID */
10360#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010362#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010363#ifdef HAVE_GETGROUPLIST
10364 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10365#endif
Fred Drakec9680921999-12-13 16:37:25 +000010366#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010370#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010372#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010373#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010375#endif /* HAVE_GETPPID */
10376#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010378#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010379#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010381#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010382#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010384#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010385#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010387#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010388#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010390#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010391#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10393 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010394#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010395#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010397#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010398#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010400#endif /* HAVE_SETEUID */
10401#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010403#endif /* HAVE_SETEGID */
10404#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010406#endif /* HAVE_SETREUID */
10407#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010408 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010409#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010410#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010412#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010413#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010415#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010416#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010418#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010419#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010421#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010422#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010423 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010424#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010425#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010426 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010427#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010428#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010429 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010430#endif /* HAVE_WAIT3 */
10431#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010432 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010433#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010434#if defined(HAVE_WAITID) && !defined(__APPLE__)
10435 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10436#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010437#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010438 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010439#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010440#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010441 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010442#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010443#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010444 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010445#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010446#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010447 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010448#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010449#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010451#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010452#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010453 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010454#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010455 {"open", (PyCFunction)posix_open,\
10456 METH_VARARGS | METH_KEYWORDS,
10457 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10459 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10460 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10461 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10462 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010463#ifdef HAVE_LOCKF
10464 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10465#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10467 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010468#ifdef HAVE_READV
10469 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10470#endif
10471#ifdef HAVE_PREAD
10472 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10473#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010474 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010475#ifdef HAVE_WRITEV
10476 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10477#endif
10478#ifdef HAVE_PWRITE
10479 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10480#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010481#ifdef HAVE_SENDFILE
10482 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10483 posix_sendfile__doc__},
10484#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010485 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010487#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010489#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010490#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010491 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010492#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010493#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070010494 {"mkfifo", (PyCFunction)posix_mkfifo,
10495 METH_VARARGS | METH_KEYWORDS,
10496 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010497#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010498#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010499 {"mknod", (PyCFunction)posix_mknod,
10500 METH_VARARGS | METH_KEYWORDS,
10501 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010502#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010503#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010504 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10505 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10506 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010507#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010508#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010510#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010511#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020010512 {"truncate", (PyCFunction)posix_truncate,
10513 METH_VARARGS | METH_KEYWORDS,
10514 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010515#endif
10516#ifdef HAVE_POSIX_FALLOCATE
10517 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10518#endif
10519#ifdef HAVE_POSIX_FADVISE
10520 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10521#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010522#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010523 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010524#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010525#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010526 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010527#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010529#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010530 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010531#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010532#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010533 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010534#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010535#ifdef HAVE_SYNC
10536 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10537#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010538#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010540#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010541#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010542#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010544#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010545#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010546 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010547#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010548#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010550#endif /* WIFSTOPPED */
10551#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010552 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010553#endif /* WIFSIGNALED */
10554#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010556#endif /* WIFEXITED */
10557#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010558 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010559#endif /* WEXITSTATUS */
10560#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010561 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010562#endif /* WTERMSIG */
10563#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010564 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010565#endif /* WSTOPSIG */
10566#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010567#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010569#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010570#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010571 {"statvfs", (PyCFunction)posix_statvfs,
10572 METH_VARARGS | METH_KEYWORDS,
10573 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010574#endif
Fred Drakec9680921999-12-13 16:37:25 +000010575#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010576 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010577#endif
10578#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010580#endif
10581#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010582 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010583#endif
10584#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020010585 {"pathconf", (PyCFunction)posix_pathconf,
10586 METH_VARARGS | METH_KEYWORDS,
10587 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010588#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010589 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010590#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010591 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010592 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010593 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010594 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010595#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010596#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010598#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010599 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010600#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010602#endif
10603#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010605#endif
10606#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010608#endif
10609#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010610 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010611#endif
10612
Benjamin Peterson9428d532011-09-14 11:45:52 -040010613#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010614 {"setxattr", (PyCFunction)posix_setxattr,
10615 METH_VARARGS | METH_KEYWORDS,
10616 posix_setxattr__doc__},
10617 {"getxattr", (PyCFunction)posix_getxattr,
10618 METH_VARARGS | METH_KEYWORDS,
10619 posix_getxattr__doc__},
10620 {"removexattr", (PyCFunction)posix_removexattr,
10621 METH_VARARGS | METH_KEYWORDS,
10622 posix_removexattr__doc__},
10623 {"listxattr", (PyCFunction)posix_listxattr,
10624 METH_VARARGS | METH_KEYWORDS,
10625 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040010626#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010627#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10628 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
10629#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010631};
10632
10633
Barry Warsaw4a342091996-12-19 23:50:02 +000010634static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010635ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010636{
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010638}
10639
Brian Curtin52173d42010-12-02 18:29:18 +000010640#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010641static int
Brian Curtin52173d42010-12-02 18:29:18 +000010642enable_symlink()
10643{
10644 HANDLE tok;
10645 TOKEN_PRIVILEGES tok_priv;
10646 LUID luid;
10647 int meth_idx = 0;
10648
10649 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010650 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010651
10652 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010653 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010654
10655 tok_priv.PrivilegeCount = 1;
10656 tok_priv.Privileges[0].Luid = luid;
10657 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
10658
10659 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
10660 sizeof(TOKEN_PRIVILEGES),
10661 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010662 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010663
Brian Curtin3b4499c2010-12-28 14:31:47 +000010664 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
10665 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000010666}
10667#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
10668
Barry Warsaw4a342091996-12-19 23:50:02 +000010669static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000010670all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000010671{
Guido van Rossum94f6f721999-01-06 18:42:14 +000010672#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010673 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010674#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010675#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010677#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010678#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010680#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010681#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010682 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010683#endif
Fred Drakec9680921999-12-13 16:37:25 +000010684#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000010686#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010687#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010689#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010690#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010691 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010692#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010693#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000010694 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010695#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010696#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000010697 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010698#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010699#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010701#endif
10702#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010703 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010704#endif
10705#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010707#endif
10708#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010710#endif
10711#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010713#endif
10714#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000010715 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010716#endif
10717#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010719#endif
10720#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010722#endif
10723#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010724 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010725#endif
10726#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010728#endif
10729#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010730 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010731#endif
10732#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010734#endif
10735#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010736 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010737#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000010738#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010740#endif
10741#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000010742 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010743#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010744#ifdef O_XATTR
10745 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
10746#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010747#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010749#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000010750#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010752#endif
10753#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010754 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010755#endif
Jesus Ceacf381202012-04-24 20:44:40 +020010756#ifdef O_EXEC
10757 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
10758#endif
10759#ifdef O_SEARCH
10760 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
10761#endif
10762#ifdef O_TTY_INIT
10763 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
10764#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010765#ifdef PRIO_PROCESS
10766 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
10767#endif
10768#ifdef PRIO_PGRP
10769 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
10770#endif
10771#ifdef PRIO_USER
10772 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
10773#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020010774#ifdef O_CLOEXEC
10775 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
10776#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010777#ifdef O_ACCMODE
10778 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
10779#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010780
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010781
Jesus Cea94363612012-06-22 18:32:07 +020010782#ifdef SEEK_HOLE
10783 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
10784#endif
10785#ifdef SEEK_DATA
10786 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
10787#endif
10788
Tim Peters5aa91602002-01-30 05:46:57 +000010789/* MS Windows */
10790#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010791 /* Don't inherit in child processes. */
10792 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010793#endif
10794#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000010795 /* Optimize for short life (keep in memory). */
10796 /* MS forgot to define this one with a non-underscore form too. */
10797 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010798#endif
10799#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010800 /* Automatically delete when last handle is closed. */
10801 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010802#endif
10803#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000010804 /* Optimize for random access. */
10805 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010806#endif
10807#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 /* Optimize for sequential access. */
10809 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010810#endif
10811
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010812/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010813#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 /* Send a SIGIO signal whenever input or output
10815 becomes available on file descriptor */
10816 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010817#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010818#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010819 /* Direct disk access. */
10820 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010821#endif
10822#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 /* Must be a directory. */
10824 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010825#endif
10826#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000010827 /* Do not follow links. */
10828 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010829#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010830#ifdef O_NOLINKS
10831 /* Fails if link count of the named file is greater than 1 */
10832 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
10833#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010834#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 /* Do not update the access time. */
10836 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010837#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000010838
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010840#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010842#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010843#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010845#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010846#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010848#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010849#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010851#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010852#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010854#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010855#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010857#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010858#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010860#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010861#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000010862 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010863#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010864#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010866#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010867#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010869#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010870#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010872#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010873#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010874 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010875#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010876#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000010877 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010878#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010879#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000010880 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010881#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010882#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010883 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010884#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010885#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010887#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010888#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000010889 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010890#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010891
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010892 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010893#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010894 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010895#endif /* ST_RDONLY */
10896#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010897 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010898#endif /* ST_NOSUID */
10899
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010900 /* FreeBSD sendfile() constants */
10901#ifdef SF_NODISKIO
10902 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
10903#endif
10904#ifdef SF_MNOWAIT
10905 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
10906#endif
10907#ifdef SF_SYNC
10908 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
10909#endif
10910
Ross Lagerwall7807c352011-03-17 20:20:30 +020010911 /* constants for posix_fadvise */
10912#ifdef POSIX_FADV_NORMAL
10913 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
10914#endif
10915#ifdef POSIX_FADV_SEQUENTIAL
10916 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
10917#endif
10918#ifdef POSIX_FADV_RANDOM
10919 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
10920#endif
10921#ifdef POSIX_FADV_NOREUSE
10922 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
10923#endif
10924#ifdef POSIX_FADV_WILLNEED
10925 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
10926#endif
10927#ifdef POSIX_FADV_DONTNEED
10928 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
10929#endif
10930
10931 /* constants for waitid */
10932#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
10933 if (ins(d, "P_PID", (long)P_PID)) return -1;
10934 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
10935 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
10936#endif
10937#ifdef WEXITED
10938 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
10939#endif
10940#ifdef WNOWAIT
10941 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
10942#endif
10943#ifdef WSTOPPED
10944 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
10945#endif
10946#ifdef CLD_EXITED
10947 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
10948#endif
10949#ifdef CLD_DUMPED
10950 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
10951#endif
10952#ifdef CLD_TRAPPED
10953 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
10954#endif
10955#ifdef CLD_CONTINUED
10956 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
10957#endif
10958
10959 /* constants for lockf */
10960#ifdef F_LOCK
10961 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
10962#endif
10963#ifdef F_TLOCK
10964 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
10965#endif
10966#ifdef F_ULOCK
10967 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
10968#endif
10969#ifdef F_TEST
10970 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
10971#endif
10972
Guido van Rossum246bc171999-02-01 23:54:31 +000010973#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010974 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
10975 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
10976 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
10977 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
10978 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000010979#endif
10980
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010981#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020010982 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010983 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
10984 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
10985#ifdef SCHED_SPORADIC
10986 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
10987#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010988#ifdef SCHED_BATCH
10989 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
10990#endif
10991#ifdef SCHED_IDLE
10992 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
10993#endif
10994#ifdef SCHED_RESET_ON_FORK
10995 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
10996#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020010997#ifdef SCHED_SYS
10998 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
10999#endif
11000#ifdef SCHED_IA
11001 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11002#endif
11003#ifdef SCHED_FSS
11004 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11005#endif
11006#ifdef SCHED_FX
11007 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11008#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011009#endif
11010
Benjamin Peterson9428d532011-09-14 11:45:52 -040011011#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011012 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11013 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11014 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11015#endif
11016
Victor Stinner8b905bd2011-10-25 13:34:04 +020011017#ifdef RTLD_LAZY
11018 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11019#endif
11020#ifdef RTLD_NOW
11021 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11022#endif
11023#ifdef RTLD_GLOBAL
11024 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11025#endif
11026#ifdef RTLD_LOCAL
11027 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11028#endif
11029#ifdef RTLD_NODELETE
11030 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11031#endif
11032#ifdef RTLD_NOLOAD
11033 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11034#endif
11035#ifdef RTLD_DEEPBIND
11036 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11037#endif
11038
Victor Stinner8c62be82010-05-06 00:08:46 +000011039 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011040}
11041
11042
Tim Peters5aa91602002-01-30 05:46:57 +000011043#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011044#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011045#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011046
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011047#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011048#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011049#define MODNAME "posix"
11050#endif
11051
Martin v. Löwis1a214512008-06-11 05:26:20 +000011052static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 PyModuleDef_HEAD_INIT,
11054 MODNAME,
11055 posix__doc__,
11056 -1,
11057 posix_methods,
11058 NULL,
11059 NULL,
11060 NULL,
11061 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011062};
11063
11064
Larry Hastings9cf065c2012-06-22 16:30:09 -070011065static char *have_functions[] = {
11066
11067#ifdef HAVE_FACCESSAT
11068 "HAVE_FACCESSAT",
11069#endif
11070
11071#ifdef HAVE_FCHDIR
11072 "HAVE_FCHDIR",
11073#endif
11074
11075#ifdef HAVE_FCHMOD
11076 "HAVE_FCHMOD",
11077#endif
11078
11079#ifdef HAVE_FCHMODAT
11080 "HAVE_FCHMODAT",
11081#endif
11082
11083#ifdef HAVE_FCHOWN
11084 "HAVE_FCHOWN",
11085#endif
11086
11087#ifdef HAVE_FEXECVE
11088 "HAVE_FEXECVE",
11089#endif
11090
11091#ifdef HAVE_FDOPENDIR
11092 "HAVE_FDOPENDIR",
11093#endif
11094
Georg Brandl306336b2012-06-24 12:55:33 +020011095#ifdef HAVE_FPATHCONF
11096 "HAVE_FPATHCONF",
11097#endif
11098
Larry Hastings9cf065c2012-06-22 16:30:09 -070011099#ifdef HAVE_FSTATAT
11100 "HAVE_FSTATAT",
11101#endif
11102
11103#ifdef HAVE_FSTATVFS
11104 "HAVE_FSTATVFS",
11105#endif
11106
Georg Brandl306336b2012-06-24 12:55:33 +020011107#ifdef HAVE_FTRUNCATE
11108 "HAVE_FTRUNCATE",
11109#endif
11110
Larry Hastings9cf065c2012-06-22 16:30:09 -070011111#ifdef HAVE_FUTIMENS
11112 "HAVE_FUTIMENS",
11113#endif
11114
11115#ifdef HAVE_FUTIMES
11116 "HAVE_FUTIMES",
11117#endif
11118
11119#ifdef HAVE_FUTIMESAT
11120 "HAVE_FUTIMESAT",
11121#endif
11122
11123#ifdef HAVE_LINKAT
11124 "HAVE_LINKAT",
11125#endif
11126
11127#ifdef HAVE_LCHFLAGS
11128 "HAVE_LCHFLAGS",
11129#endif
11130
11131#ifdef HAVE_LCHMOD
11132 "HAVE_LCHMOD",
11133#endif
11134
11135#ifdef HAVE_LCHOWN
11136 "HAVE_LCHOWN",
11137#endif
11138
11139#ifdef HAVE_LSTAT
11140 "HAVE_LSTAT",
11141#endif
11142
11143#ifdef HAVE_LUTIMES
11144 "HAVE_LUTIMES",
11145#endif
11146
11147#ifdef HAVE_MKDIRAT
11148 "HAVE_MKDIRAT",
11149#endif
11150
11151#ifdef HAVE_MKFIFOAT
11152 "HAVE_MKFIFOAT",
11153#endif
11154
11155#ifdef HAVE_MKNODAT
11156 "HAVE_MKNODAT",
11157#endif
11158
11159#ifdef HAVE_OPENAT
11160 "HAVE_OPENAT",
11161#endif
11162
11163#ifdef HAVE_READLINKAT
11164 "HAVE_READLINKAT",
11165#endif
11166
11167#ifdef HAVE_RENAMEAT
11168 "HAVE_RENAMEAT",
11169#endif
11170
11171#ifdef HAVE_SYMLINKAT
11172 "HAVE_SYMLINKAT",
11173#endif
11174
11175#ifdef HAVE_UNLINKAT
11176 "HAVE_UNLINKAT",
11177#endif
11178
11179#ifdef HAVE_UTIMENSAT
11180 "HAVE_UTIMENSAT",
11181#endif
11182
11183#ifdef MS_WINDOWS
11184 "MS_WINDOWS",
11185#endif
11186
11187 NULL
11188};
11189
11190
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011191PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011192INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011193{
Victor Stinner8c62be82010-05-06 00:08:46 +000011194 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011195 PyObject *list;
11196 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011197
Brian Curtin52173d42010-12-02 18:29:18 +000011198#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011199 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011200#endif
11201
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 m = PyModule_Create(&posixmodule);
11203 if (m == NULL)
11204 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011205
Victor Stinner8c62be82010-05-06 00:08:46 +000011206 /* Initialize environ dictionary */
11207 v = convertenviron();
11208 Py_XINCREF(v);
11209 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11210 return NULL;
11211 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011212
Victor Stinner8c62be82010-05-06 00:08:46 +000011213 if (all_ins(m))
11214 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011215
Victor Stinner8c62be82010-05-06 00:08:46 +000011216 if (setup_confname_tables(m))
11217 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011218
Victor Stinner8c62be82010-05-06 00:08:46 +000011219 Py_INCREF(PyExc_OSError);
11220 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011221
Guido van Rossumb3d39562000-01-31 18:41:26 +000011222#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 if (posix_putenv_garbage == NULL)
11224 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011225#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011226
Victor Stinner8c62be82010-05-06 00:08:46 +000011227 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011228#if defined(HAVE_WAITID) && !defined(__APPLE__)
11229 waitid_result_desc.name = MODNAME ".waitid_result";
11230 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11231#endif
11232
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 stat_result_desc.name = MODNAME ".stat_result";
11234 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11235 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11236 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11237 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11238 structseq_new = StatResultType.tp_new;
11239 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011240
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 statvfs_result_desc.name = MODNAME ".statvfs_result";
11242 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011243#ifdef NEED_TICKS_PER_SECOND
11244# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011246# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011248# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011249 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011250# endif
11251#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011252
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011253#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011254 sched_param_desc.name = MODNAME ".sched_param";
11255 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11256 SchedParamType.tp_new = sched_param_new;
11257#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011258
11259 /* initialize TerminalSize_info */
11260 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011261 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011262#if defined(HAVE_WAITID) && !defined(__APPLE__)
11263 Py_INCREF((PyObject*) &WaitidResultType);
11264 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11265#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011266 Py_INCREF((PyObject*) &StatResultType);
11267 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11268 Py_INCREF((PyObject*) &StatVFSResultType);
11269 PyModule_AddObject(m, "statvfs_result",
11270 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011271
11272#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011273 Py_INCREF(&SchedParamType);
11274 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011275#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011276
Larry Hastings605a62d2012-06-24 04:33:36 -070011277 times_result_desc.name = MODNAME ".times_result";
11278 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11279 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11280
11281 uname_result_desc.name = MODNAME ".uname_result";
11282 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11283 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11284
Thomas Wouters477c8d52006-05-27 19:21:47 +000011285#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 /*
11287 * Step 2 of weak-linking support on Mac OS X.
11288 *
11289 * The code below removes functions that are not available on the
11290 * currently active platform.
11291 *
11292 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011293 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 * OSX 10.4.
11295 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011296#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 if (fstatvfs == NULL) {
11298 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11299 return NULL;
11300 }
11301 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011302#endif /* HAVE_FSTATVFS */
11303
11304#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 if (statvfs == NULL) {
11306 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11307 return NULL;
11308 }
11309 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011310#endif /* HAVE_STATVFS */
11311
11312# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 if (lchown == NULL) {
11314 if (PyObject_DelAttrString(m, "lchown") == -1) {
11315 return NULL;
11316 }
11317 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011318#endif /* HAVE_LCHOWN */
11319
11320
11321#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011322
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011323 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011324 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11325
Larry Hastings6fe20b32012-04-19 15:07:49 -070011326 billion = PyLong_FromLong(1000000000);
11327 if (!billion)
11328 return NULL;
11329
Larry Hastings9cf065c2012-06-22 16:30:09 -070011330 /* suppress "function not used" warnings */
11331 {
11332 int ignored;
11333 fd_specified("", -1);
11334 follow_symlinks_specified("", 1);
11335 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11336 dir_fd_converter(Py_None, &ignored);
11337 dir_fd_unavailable(Py_None, &ignored);
11338 }
11339
11340 /*
11341 * provide list of locally available functions
11342 * so os.py can populate support_* lists
11343 */
11344 list = PyList_New(0);
11345 if (!list)
11346 return NULL;
11347 for (trace = have_functions; *trace; trace++) {
11348 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11349 if (!unicode)
11350 return NULL;
11351 if (PyList_Append(list, unicode))
11352 return NULL;
11353 Py_DECREF(unicode);
11354 }
11355 PyModule_AddObject(m, "_have_functions", list);
11356
11357 initialized = 1;
11358
Victor Stinner8c62be82010-05-06 00:08:46 +000011359 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011360
Guido van Rossumb6775db1994-08-01 11:34:53 +000011361}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011362
11363#ifdef __cplusplus
11364}
11365#endif