blob: fb58507bf635268d3e0e38cccd3e190e83b784da [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 */
Jack Jansenea0c3822002-08-01 21:57:49 +0000927#ifdef WITH_NEXT_FRAMEWORK
928/* On Darwin/MacOSX a shared library or framework has no access to
929** environ directly, we must obtain it with _NSGetEnviron().
930*/
931#include <crt_externs.h>
932static char **environ;
933#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000934extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000935#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000936
Barry Warsaw53699e91996-12-10 23:23:01 +0000937static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000938convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000939{
Victor Stinner8c62be82010-05-06 00:08:46 +0000940 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000941#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000942 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000943#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000944 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000945#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000946
Victor Stinner8c62be82010-05-06 00:08:46 +0000947 d = PyDict_New();
948 if (d == NULL)
949 return NULL;
950#ifdef WITH_NEXT_FRAMEWORK
951 if (environ == NULL)
952 environ = *_NSGetEnviron();
953#endif
954#ifdef MS_WINDOWS
955 /* _wenviron must be initialized in this way if the program is started
956 through main() instead of wmain(). */
957 _wgetenv(L"");
958 if (_wenviron == NULL)
959 return d;
960 /* This part ignores errors */
961 for (e = _wenviron; *e != NULL; e++) {
962 PyObject *k;
963 PyObject *v;
964 wchar_t *p = wcschr(*e, L'=');
965 if (p == NULL)
966 continue;
967 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
968 if (k == NULL) {
969 PyErr_Clear();
970 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000971 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000972 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
973 if (v == NULL) {
974 PyErr_Clear();
975 Py_DECREF(k);
976 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000977 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000978 if (PyDict_GetItem(d, k) == NULL) {
979 if (PyDict_SetItem(d, k, v) != 0)
980 PyErr_Clear();
981 }
982 Py_DECREF(k);
983 Py_DECREF(v);
984 }
985#else
986 if (environ == NULL)
987 return d;
988 /* This part ignores errors */
989 for (e = environ; *e != NULL; e++) {
990 PyObject *k;
991 PyObject *v;
992 char *p = strchr(*e, '=');
993 if (p == NULL)
994 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000995 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000996 if (k == NULL) {
997 PyErr_Clear();
998 continue;
999 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001000 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001001 if (v == NULL) {
1002 PyErr_Clear();
1003 Py_DECREF(k);
1004 continue;
1005 }
1006 if (PyDict_GetItem(d, k) == NULL) {
1007 if (PyDict_SetItem(d, k, v) != 0)
1008 PyErr_Clear();
1009 }
1010 Py_DECREF(k);
1011 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001012 }
1013#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001014 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001015}
1016
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001017/* Set a POSIX-specific error from errno, and return NULL */
1018
Barry Warsawd58d7641998-07-23 16:14:40 +00001019static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001020posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001021{
Victor Stinner8c62be82010-05-06 00:08:46 +00001022 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001023}
Mark Hammondef8b6542001-05-13 08:04:26 +00001024
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001025#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001026static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001027win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001028{
Victor Stinner8c62be82010-05-06 00:08:46 +00001029 /* XXX We should pass the function name along in the future.
1030 (winreg.c also wants to pass the function name.)
1031 This would however require an additional param to the
1032 Windows error object, which is non-trivial.
1033 */
1034 errno = GetLastError();
1035 if (filename)
1036 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1037 else
1038 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001039}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001040
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001041static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001042win32_error_object(char* function, PyObject* filename)
1043{
1044 /* XXX - see win32_error for comments on 'function' */
1045 errno = GetLastError();
1046 if (filename)
1047 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001048 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001049 errno,
1050 filename);
1051 else
1052 return PyErr_SetFromWindowsErr(errno);
1053}
1054
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001055#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001056
Larry Hastings9cf065c2012-06-22 16:30:09 -07001057static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001058path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001059{
1060#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001061 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1062 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001063#else
Victor Stinner292c8352012-10-30 02:17:38 +01001064 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065#endif
1066}
1067
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001068/* POSIX generic methods */
1069
Barry Warsaw53699e91996-12-10 23:23:01 +00001070static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001071posix_fildes(PyObject *fdobj, int (*func)(int))
1072{
Victor Stinner8c62be82010-05-06 00:08:46 +00001073 int fd;
1074 int res;
1075 fd = PyObject_AsFileDescriptor(fdobj);
1076 if (fd < 0)
1077 return NULL;
1078 if (!_PyVerify_fd(fd))
1079 return posix_error();
1080 Py_BEGIN_ALLOW_THREADS
1081 res = (*func)(fd);
1082 Py_END_ALLOW_THREADS
1083 if (res < 0)
1084 return posix_error();
1085 Py_INCREF(Py_None);
1086 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001087}
Guido van Rossum21142a01999-01-08 21:05:37 +00001088
1089static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001090posix_1str(const char *func_name, PyObject *args, char *format,
1091 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001092{
Victor Stinner292c8352012-10-30 02:17:38 +01001093 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001094 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001095 memset(&path, 0, sizeof(path));
1096 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001097 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001098 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001099 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001100 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001101 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001102 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001103 if (res < 0) {
1104 path_error(&path);
1105 path_cleanup(&path);
1106 return NULL;
1107 }
1108 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001109 Py_INCREF(Py_None);
1110 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001111}
1112
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001113
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001114#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001115/* This is a reimplementation of the C library's chdir function,
1116 but one that produces Win32 errors instead of DOS error codes.
1117 chdir is essentially a wrapper around SetCurrentDirectory; however,
1118 it also needs to set "magic" environment variables indicating
1119 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001120static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001121win32_chdir(LPCSTR path)
1122{
Victor Stinner8c62be82010-05-06 00:08:46 +00001123 char new_path[MAX_PATH+1];
1124 int result;
1125 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001126
Victor Stinner8c62be82010-05-06 00:08:46 +00001127 if(!SetCurrentDirectoryA(path))
1128 return FALSE;
1129 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1130 if (!result)
1131 return FALSE;
1132 /* In the ANSI API, there should not be any paths longer
1133 than MAX_PATH. */
1134 assert(result <= MAX_PATH+1);
1135 if (strncmp(new_path, "\\\\", 2) == 0 ||
1136 strncmp(new_path, "//", 2) == 0)
1137 /* UNC path, nothing to do. */
1138 return TRUE;
1139 env[1] = new_path[0];
1140 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001141}
1142
1143/* The Unicode version differs from the ANSI version
1144 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001145static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001146win32_wchdir(LPCWSTR path)
1147{
Victor Stinner8c62be82010-05-06 00:08:46 +00001148 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1149 int result;
1150 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001151
Victor Stinner8c62be82010-05-06 00:08:46 +00001152 if(!SetCurrentDirectoryW(path))
1153 return FALSE;
1154 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1155 if (!result)
1156 return FALSE;
1157 if (result > MAX_PATH+1) {
1158 new_path = malloc(result * sizeof(wchar_t));
1159 if (!new_path) {
1160 SetLastError(ERROR_OUTOFMEMORY);
1161 return FALSE;
1162 }
1163 result = GetCurrentDirectoryW(result, new_path);
1164 if (!result) {
1165 free(new_path);
1166 return FALSE;
1167 }
1168 }
1169 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1170 wcsncmp(new_path, L"//", 2) == 0)
1171 /* UNC path, nothing to do. */
1172 return TRUE;
1173 env[1] = new_path[0];
1174 result = SetEnvironmentVariableW(env, new_path);
1175 if (new_path != _new_path)
1176 free(new_path);
1177 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001178}
1179#endif
1180
Martin v. Löwis14694662006-02-03 12:54:16 +00001181#ifdef MS_WINDOWS
1182/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1183 - time stamps are restricted to second resolution
1184 - file modification times suffer from forth-and-back conversions between
1185 UTC and local time
1186 Therefore, we implement our own stat, based on the Win32 API directly.
1187*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001188#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001189
1190struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001191 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001192 __int64 st_ino;
1193 unsigned short st_mode;
1194 int st_nlink;
1195 int st_uid;
1196 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001197 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001198 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001199 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001200 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001201 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001202 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001203 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001204 int st_ctime_nsec;
1205};
1206
1207static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1208
1209static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001210FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001211{
Victor Stinner8c62be82010-05-06 00:08:46 +00001212 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1213 /* Cannot simply cast and dereference in_ptr,
1214 since it might not be aligned properly */
1215 __int64 in;
1216 memcpy(&in, in_ptr, sizeof(in));
1217 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001218 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001219}
1220
Thomas Wouters477c8d52006-05-27 19:21:47 +00001221static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001222time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001223{
Victor Stinner8c62be82010-05-06 00:08:46 +00001224 /* XXX endianness */
1225 __int64 out;
1226 out = time_in + secs_between_epochs;
1227 out = out * 10000000 + nsec_in / 100;
1228 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001229}
1230
Martin v. Löwis14694662006-02-03 12:54:16 +00001231/* Below, we *know* that ugo+r is 0444 */
1232#if _S_IREAD != 0400
1233#error Unsupported C library
1234#endif
1235static int
1236attributes_to_mode(DWORD attr)
1237{
Victor Stinner8c62be82010-05-06 00:08:46 +00001238 int m = 0;
1239 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1240 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1241 else
1242 m |= _S_IFREG;
1243 if (attr & FILE_ATTRIBUTE_READONLY)
1244 m |= 0444;
1245 else
1246 m |= 0666;
1247 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001248}
1249
1250static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001251attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001252{
Victor Stinner8c62be82010-05-06 00:08:46 +00001253 memset(result, 0, sizeof(*result));
1254 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1255 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001256 result->st_dev = info->dwVolumeSerialNumber;
1257 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001258 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1259 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1260 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001261 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001262 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001263 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1264 /* first clear the S_IFMT bits */
1265 result->st_mode ^= (result->st_mode & 0170000);
1266 /* now set the bits that make this a symlink */
1267 result->st_mode |= 0120000;
1268 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001269
Victor Stinner8c62be82010-05-06 00:08:46 +00001270 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001271}
1272
Guido van Rossumd8faa362007-04-27 19:54:29 +00001273static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001274attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001275{
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 HANDLE hFindFile;
1277 WIN32_FIND_DATAA FileData;
1278 hFindFile = FindFirstFileA(pszFile, &FileData);
1279 if (hFindFile == INVALID_HANDLE_VALUE)
1280 return FALSE;
1281 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001282 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001283 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001284 info->dwFileAttributes = FileData.dwFileAttributes;
1285 info->ftCreationTime = FileData.ftCreationTime;
1286 info->ftLastAccessTime = FileData.ftLastAccessTime;
1287 info->ftLastWriteTime = FileData.ftLastWriteTime;
1288 info->nFileSizeHigh = FileData.nFileSizeHigh;
1289 info->nFileSizeLow = FileData.nFileSizeLow;
1290/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001291 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1292 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001293 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001294}
1295
1296static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001297attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001298{
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 HANDLE hFindFile;
1300 WIN32_FIND_DATAW FileData;
1301 hFindFile = FindFirstFileW(pszFile, &FileData);
1302 if (hFindFile == INVALID_HANDLE_VALUE)
1303 return FALSE;
1304 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001305 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001306 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001307 info->dwFileAttributes = FileData.dwFileAttributes;
1308 info->ftCreationTime = FileData.ftCreationTime;
1309 info->ftLastAccessTime = FileData.ftLastAccessTime;
1310 info->ftLastWriteTime = FileData.ftLastWriteTime;
1311 info->nFileSizeHigh = FileData.nFileSizeHigh;
1312 info->nFileSizeLow = FileData.nFileSizeLow;
1313/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001314 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1315 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001316 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001317}
1318
Brian Curtind25aef52011-06-13 15:16:04 -05001319/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001320static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001321static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1322 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001323static int
Brian Curtind25aef52011-06-13 15:16:04 -05001324check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001325{
Brian Curtind25aef52011-06-13 15:16:04 -05001326 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001327 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1328 DWORD);
1329
Brian Curtind25aef52011-06-13 15:16:04 -05001330 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001331 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001332 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001333 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001334 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1335 "GetFinalPathNameByHandleA");
1336 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1337 "GetFinalPathNameByHandleW");
1338 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1339 Py_GetFinalPathNameByHandleW;
1340 }
1341 return has_GetFinalPathNameByHandle;
1342}
1343
1344static BOOL
1345get_target_path(HANDLE hdl, wchar_t **target_path)
1346{
1347 int buf_size, result_length;
1348 wchar_t *buf;
1349
1350 /* We have a good handle to the target, use it to determine
1351 the target path name (then we'll call lstat on it). */
1352 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1353 VOLUME_NAME_DOS);
1354 if(!buf_size)
1355 return FALSE;
1356
1357 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001358 if (!buf) {
1359 SetLastError(ERROR_OUTOFMEMORY);
1360 return FALSE;
1361 }
1362
Brian Curtind25aef52011-06-13 15:16:04 -05001363 result_length = Py_GetFinalPathNameByHandleW(hdl,
1364 buf, buf_size, VOLUME_NAME_DOS);
1365
1366 if(!result_length) {
1367 free(buf);
1368 return FALSE;
1369 }
1370
1371 if(!CloseHandle(hdl)) {
1372 free(buf);
1373 return FALSE;
1374 }
1375
1376 buf[result_length] = 0;
1377
1378 *target_path = buf;
1379 return TRUE;
1380}
1381
1382static int
1383win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1384 BOOL traverse);
1385static int
1386win32_xstat_impl(const char *path, struct win32_stat *result,
1387 BOOL traverse)
1388{
Victor Stinner26de69d2011-06-17 15:15:38 +02001389 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001390 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001391 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001392 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001393 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001394 const char *dot;
1395
Brian Curtind25aef52011-06-13 15:16:04 -05001396 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001397 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1398 traverse reparse point. */
1399 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001400 }
1401
Brian Curtinf5e76d02010-11-24 13:14:05 +00001402 hFile = CreateFileA(
1403 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001404 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001405 0, /* share mode */
1406 NULL, /* security attributes */
1407 OPEN_EXISTING,
1408 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001409 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1410 Because of this, calls like GetFinalPathNameByHandle will return
1411 the symlink path agin and not the actual final path. */
1412 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1413 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001414 NULL);
1415
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001416 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001417 /* Either the target doesn't exist, or we don't have access to
1418 get a handle to it. If the former, we need to return an error.
1419 If the latter, we can use attributes_from_dir. */
1420 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001421 return -1;
1422 /* Could not get attributes on open file. Fall back to
1423 reading the directory. */
1424 if (!attributes_from_dir(path, &info, &reparse_tag))
1425 /* Very strange. This should not fail now */
1426 return -1;
1427 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1428 if (traverse) {
1429 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001430 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001431 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001432 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001433 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001434 } else {
1435 if (!GetFileInformationByHandle(hFile, &info)) {
1436 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001437 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001438 }
1439 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001440 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1441 return -1;
1442
1443 /* Close the outer open file handle now that we're about to
1444 reopen it with different flags. */
1445 if (!CloseHandle(hFile))
1446 return -1;
1447
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001448 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001449 /* In order to call GetFinalPathNameByHandle we need to open
1450 the file without the reparse handling flag set. */
1451 hFile2 = CreateFileA(
1452 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1453 NULL, OPEN_EXISTING,
1454 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1455 NULL);
1456 if (hFile2 == INVALID_HANDLE_VALUE)
1457 return -1;
1458
1459 if (!get_target_path(hFile2, &target_path))
1460 return -1;
1461
1462 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001463 free(target_path);
1464 return code;
1465 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001466 } else
1467 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001468 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001469 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001470
1471 /* Set S_IEXEC if it is an .exe, .bat, ... */
1472 dot = strrchr(path, '.');
1473 if (dot) {
1474 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1475 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1476 result->st_mode |= 0111;
1477 }
1478 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001479}
1480
1481static int
Brian Curtind25aef52011-06-13 15:16:04 -05001482win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1483 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001484{
1485 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001486 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001487 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001488 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001489 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001490 const wchar_t *dot;
1491
Brian Curtind25aef52011-06-13 15:16:04 -05001492 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001493 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1494 traverse reparse point. */
1495 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001496 }
1497
Brian Curtinf5e76d02010-11-24 13:14:05 +00001498 hFile = CreateFileW(
1499 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001500 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001501 0, /* share mode */
1502 NULL, /* security attributes */
1503 OPEN_EXISTING,
1504 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001505 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1506 Because of this, calls like GetFinalPathNameByHandle will return
1507 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001508 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001509 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001510 NULL);
1511
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001512 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001513 /* Either the target doesn't exist, or we don't have access to
1514 get a handle to it. If the former, we need to return an error.
1515 If the latter, we can use attributes_from_dir. */
1516 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001517 return -1;
1518 /* Could not get attributes on open file. Fall back to
1519 reading the directory. */
1520 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1521 /* Very strange. This should not fail now */
1522 return -1;
1523 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1524 if (traverse) {
1525 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001526 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001527 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001528 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001529 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001530 } else {
1531 if (!GetFileInformationByHandle(hFile, &info)) {
1532 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001533 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001534 }
1535 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001536 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1537 return -1;
1538
1539 /* Close the outer open file handle now that we're about to
1540 reopen it with different flags. */
1541 if (!CloseHandle(hFile))
1542 return -1;
1543
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001544 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001545 /* In order to call GetFinalPathNameByHandle we need to open
1546 the file without the reparse handling flag set. */
1547 hFile2 = CreateFileW(
1548 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1549 NULL, OPEN_EXISTING,
1550 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1551 NULL);
1552 if (hFile2 == INVALID_HANDLE_VALUE)
1553 return -1;
1554
1555 if (!get_target_path(hFile2, &target_path))
1556 return -1;
1557
1558 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001559 free(target_path);
1560 return code;
1561 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001562 } else
1563 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001564 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001565 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001566
1567 /* Set S_IEXEC if it is an .exe, .bat, ... */
1568 dot = wcsrchr(path, '.');
1569 if (dot) {
1570 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1571 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1572 result->st_mode |= 0111;
1573 }
1574 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575}
1576
1577static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001578win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001579{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001580 /* Protocol violation: we explicitly clear errno, instead of
1581 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001582 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001583 errno = 0;
1584 return code;
1585}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001587static int
1588win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1589{
1590 /* Protocol violation: we explicitly clear errno, instead of
1591 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001592 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001593 errno = 0;
1594 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001595}
Brian Curtind25aef52011-06-13 15:16:04 -05001596/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001597
1598 In Posix, stat automatically traverses symlinks and returns the stat
1599 structure for the target. In Windows, the equivalent GetFileAttributes by
1600 default does not traverse symlinks and instead returns attributes for
1601 the symlink.
1602
1603 Therefore, win32_lstat will get the attributes traditionally, and
1604 win32_stat will first explicitly resolve the symlink target and then will
1605 call win32_lstat on that result.
1606
Ezio Melotti4969f702011-03-15 05:59:46 +02001607 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001608
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001609static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001610win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001611{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001612 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001613}
1614
Victor Stinner8c62be82010-05-06 00:08:46 +00001615static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001616win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001617{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001618 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001619}
1620
1621static int
1622win32_stat(const char* path, struct win32_stat *result)
1623{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001624 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001625}
1626
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001627static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001628win32_stat_w(const wchar_t* path, struct win32_stat *result)
1629{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001631}
1632
1633static int
1634win32_fstat(int file_number, struct win32_stat *result)
1635{
Victor Stinner8c62be82010-05-06 00:08:46 +00001636 BY_HANDLE_FILE_INFORMATION info;
1637 HANDLE h;
1638 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001639
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001640 if (!_PyVerify_fd(file_number))
1641 h = INVALID_HANDLE_VALUE;
1642 else
1643 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001644
Victor Stinner8c62be82010-05-06 00:08:46 +00001645 /* Protocol violation: we explicitly clear errno, instead of
1646 setting it to a POSIX error. Callers should use GetLastError. */
1647 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001648
Victor Stinner8c62be82010-05-06 00:08:46 +00001649 if (h == INVALID_HANDLE_VALUE) {
1650 /* This is really a C library error (invalid file handle).
1651 We set the Win32 error to the closes one matching. */
1652 SetLastError(ERROR_INVALID_HANDLE);
1653 return -1;
1654 }
1655 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001656
Victor Stinner8c62be82010-05-06 00:08:46 +00001657 type = GetFileType(h);
1658 if (type == FILE_TYPE_UNKNOWN) {
1659 DWORD error = GetLastError();
1660 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001661 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001662 }
1663 /* else: valid but unknown file */
1664 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001665
Victor Stinner8c62be82010-05-06 00:08:46 +00001666 if (type != FILE_TYPE_DISK) {
1667 if (type == FILE_TYPE_CHAR)
1668 result->st_mode = _S_IFCHR;
1669 else if (type == FILE_TYPE_PIPE)
1670 result->st_mode = _S_IFIFO;
1671 return 0;
1672 }
1673
1674 if (!GetFileInformationByHandle(h, &info)) {
1675 return -1;
1676 }
1677
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001678 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001679 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001680 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1681 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001682}
1683
1684#endif /* MS_WINDOWS */
1685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001686PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001687"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001688This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001689 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001690or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1691\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001692Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1693or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001694\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001695See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001696
1697static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001698 {"st_mode", "protection bits"},
1699 {"st_ino", "inode"},
1700 {"st_dev", "device"},
1701 {"st_nlink", "number of hard links"},
1702 {"st_uid", "user ID of owner"},
1703 {"st_gid", "group ID of owner"},
1704 {"st_size", "total size, in bytes"},
1705 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1706 {NULL, "integer time of last access"},
1707 {NULL, "integer time of last modification"},
1708 {NULL, "integer time of last change"},
1709 {"st_atime", "time of last access"},
1710 {"st_mtime", "time of last modification"},
1711 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001712 {"st_atime_ns", "time of last access in nanoseconds"},
1713 {"st_mtime_ns", "time of last modification in nanoseconds"},
1714 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001715#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001716 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001717#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001718#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001719 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001720#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001721#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001722 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001723#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001724#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001725 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001726#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001727#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001728 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001729#endif
1730#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001731 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001732#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001733 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001734};
1735
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001736#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001737#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001738#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001739#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001740#endif
1741
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001742#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001743#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1744#else
1745#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1746#endif
1747
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001748#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001749#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1750#else
1751#define ST_RDEV_IDX ST_BLOCKS_IDX
1752#endif
1753
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001754#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1755#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1756#else
1757#define ST_FLAGS_IDX ST_RDEV_IDX
1758#endif
1759
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001760#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001761#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001762#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001763#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001764#endif
1765
1766#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1767#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1768#else
1769#define ST_BIRTHTIME_IDX ST_GEN_IDX
1770#endif
1771
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001772static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 "stat_result", /* name */
1774 stat_result__doc__, /* doc */
1775 stat_result_fields,
1776 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001777};
1778
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001779PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1781This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001782 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001783or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001784\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001785See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001786
1787static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 {"f_bsize", },
1789 {"f_frsize", },
1790 {"f_blocks", },
1791 {"f_bfree", },
1792 {"f_bavail", },
1793 {"f_files", },
1794 {"f_ffree", },
1795 {"f_favail", },
1796 {"f_flag", },
1797 {"f_namemax",},
1798 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001799};
1800
1801static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001802 "statvfs_result", /* name */
1803 statvfs_result__doc__, /* doc */
1804 statvfs_result_fields,
1805 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001806};
1807
Ross Lagerwall7807c352011-03-17 20:20:30 +02001808#if defined(HAVE_WAITID) && !defined(__APPLE__)
1809PyDoc_STRVAR(waitid_result__doc__,
1810"waitid_result: Result from waitid.\n\n\
1811This object may be accessed either as a tuple of\n\
1812 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1813or via the attributes si_pid, si_uid, and so on.\n\
1814\n\
1815See os.waitid for more information.");
1816
1817static PyStructSequence_Field waitid_result_fields[] = {
1818 {"si_pid", },
1819 {"si_uid", },
1820 {"si_signo", },
1821 {"si_status", },
1822 {"si_code", },
1823 {0}
1824};
1825
1826static PyStructSequence_Desc waitid_result_desc = {
1827 "waitid_result", /* name */
1828 waitid_result__doc__, /* doc */
1829 waitid_result_fields,
1830 5
1831};
1832static PyTypeObject WaitidResultType;
1833#endif
1834
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001835static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001836static PyTypeObject StatResultType;
1837static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001838#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001839static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001840#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001841static newfunc structseq_new;
1842
1843static PyObject *
1844statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1845{
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 PyStructSequence *result;
1847 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001848
Victor Stinner8c62be82010-05-06 00:08:46 +00001849 result = (PyStructSequence*)structseq_new(type, args, kwds);
1850 if (!result)
1851 return NULL;
1852 /* If we have been initialized from a tuple,
1853 st_?time might be set to None. Initialize it
1854 from the int slots. */
1855 for (i = 7; i <= 9; i++) {
1856 if (result->ob_item[i+3] == Py_None) {
1857 Py_DECREF(Py_None);
1858 Py_INCREF(result->ob_item[i]);
1859 result->ob_item[i+3] = result->ob_item[i];
1860 }
1861 }
1862 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001863}
1864
1865
1866
1867/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001868static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001869
1870PyDoc_STRVAR(stat_float_times__doc__,
1871"stat_float_times([newval]) -> oldval\n\n\
1872Determine whether os.[lf]stat represents time stamps as float objects.\n\
1873If newval is True, future calls to stat() return floats, if it is False,\n\
1874future calls return ints. \n\
1875If newval is omitted, return the current setting.\n");
1876
1877static PyObject*
1878stat_float_times(PyObject* self, PyObject *args)
1879{
Victor Stinner8c62be82010-05-06 00:08:46 +00001880 int newval = -1;
1881 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1882 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001883 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1884 "stat_float_times() is deprecated",
1885 1))
1886 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 if (newval == -1)
1888 /* Return old value */
1889 return PyBool_FromLong(_stat_float_times);
1890 _stat_float_times = newval;
1891 Py_INCREF(Py_None);
1892 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001893}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001894
Larry Hastings6fe20b32012-04-19 15:07:49 -07001895static PyObject *billion = NULL;
1896
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001897static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001898fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001899{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001900 PyObject *s = _PyLong_FromTime_t(sec);
1901 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1902 PyObject *s_in_ns = NULL;
1903 PyObject *ns_total = NULL;
1904 PyObject *float_s = NULL;
1905
1906 if (!(s && ns_fractional))
1907 goto exit;
1908
1909 s_in_ns = PyNumber_Multiply(s, billion);
1910 if (!s_in_ns)
1911 goto exit;
1912
1913 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1914 if (!ns_total)
1915 goto exit;
1916
Victor Stinner4195b5c2012-02-08 23:03:19 +01001917 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001918 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1919 if (!float_s)
1920 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001921 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001922 else {
1923 float_s = s;
1924 Py_INCREF(float_s);
1925 }
1926
1927 PyStructSequence_SET_ITEM(v, index, s);
1928 PyStructSequence_SET_ITEM(v, index+3, float_s);
1929 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1930 s = NULL;
1931 float_s = NULL;
1932 ns_total = NULL;
1933exit:
1934 Py_XDECREF(s);
1935 Py_XDECREF(ns_fractional);
1936 Py_XDECREF(s_in_ns);
1937 Py_XDECREF(ns_total);
1938 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001939}
1940
Tim Peters5aa91602002-01-30 05:46:57 +00001941/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001942 (used by posix_stat() and posix_fstat()) */
1943static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001944_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001945{
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 unsigned long ansec, mnsec, cnsec;
1947 PyObject *v = PyStructSequence_New(&StatResultType);
1948 if (v == NULL)
1949 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001950
Victor Stinner8c62be82010-05-06 00:08:46 +00001951 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001952#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001953 PyStructSequence_SET_ITEM(v, 1,
1954 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001955#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001956 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001957#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001958#ifdef MS_WINDOWS
1959 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
1960#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00001961 PyStructSequence_SET_ITEM(v, 2,
1962 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001963#else
Brian Curtin9cc43212013-01-01 12:31:06 -06001964 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001965#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1967 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1968 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001969#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 PyStructSequence_SET_ITEM(v, 6,
1971 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001972#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001974#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001975
Martin v. Löwis14694662006-02-03 12:54:16 +00001976#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 ansec = st->st_atim.tv_nsec;
1978 mnsec = st->st_mtim.tv_nsec;
1979 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001980#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001981 ansec = st->st_atimespec.tv_nsec;
1982 mnsec = st->st_mtimespec.tv_nsec;
1983 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001984#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001985 ansec = st->st_atime_nsec;
1986 mnsec = st->st_mtime_nsec;
1987 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001988#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001989 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001990#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001991 fill_time(v, 7, st->st_atime, ansec);
1992 fill_time(v, 8, st->st_mtime, mnsec);
1993 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001994
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001995#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001996 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1997 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001998#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001999#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002000 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2001 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002002#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002003#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002004 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2005 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002006#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002007#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002008 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2009 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002010#endif
2011#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002012 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002013 PyObject *val;
2014 unsigned long bsec,bnsec;
2015 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002016#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002017 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002018#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002019 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002020#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002021 if (_stat_float_times) {
2022 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2023 } else {
2024 val = PyLong_FromLong((long)bsec);
2025 }
2026 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2027 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002028 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002029#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002030#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2032 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002033#endif
Fred Drake699f3522000-06-29 21:12:41 +00002034
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 if (PyErr_Occurred()) {
2036 Py_DECREF(v);
2037 return NULL;
2038 }
Fred Drake699f3522000-06-29 21:12:41 +00002039
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002041}
2042
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002043/* POSIX methods */
2044
Guido van Rossum94f6f721999-01-06 18:42:14 +00002045
2046static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002047posix_do_stat(char *function_name, path_t *path,
2048 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002049{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002050 STRUCT_STAT st;
2051 int result;
2052
2053#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2054 if (follow_symlinks_specified(function_name, follow_symlinks))
2055 return NULL;
2056#endif
2057
2058 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2059 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2060 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2061 return NULL;
2062
2063 Py_BEGIN_ALLOW_THREADS
2064 if (path->fd != -1)
2065 result = FSTAT(path->fd, &st);
2066 else
2067#ifdef MS_WINDOWS
2068 if (path->wide) {
2069 if (follow_symlinks)
2070 result = win32_stat_w(path->wide, &st);
2071 else
2072 result = win32_lstat_w(path->wide, &st);
2073 }
2074 else
2075#endif
2076#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2077 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2078 result = LSTAT(path->narrow, &st);
2079 else
2080#endif
2081#ifdef HAVE_FSTATAT
2082 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2083 result = fstatat(dir_fd, path->narrow, &st,
2084 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2085 else
2086#endif
2087 result = STAT(path->narrow, &st);
2088 Py_END_ALLOW_THREADS
2089
Victor Stinner292c8352012-10-30 02:17:38 +01002090 if (result != 0) {
2091 return path_error(path);
2092 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002093
2094 return _pystat_fromstructstat(&st);
2095}
2096
2097PyDoc_STRVAR(posix_stat__doc__,
2098"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2099Perform a stat system call on the given path.\n\
2100\n\
2101path may be specified as either a string or as an open file descriptor.\n\
2102\n\
2103If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2104 and path should be relative; path will then be relative to that directory.\n\
2105 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2106 it will raise a NotImplementedError.\n\
2107If follow_symlinks is False, and the last element of the path is a symbolic\n\
2108 link, stat will examine the symbolic link itself instead of the file the\n\
2109 link points to.\n\
2110It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2111 an open file descriptor.");
2112
2113static PyObject *
2114posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2115{
2116 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2117 path_t path;
2118 int dir_fd = DEFAULT_DIR_FD;
2119 int follow_symlinks = 1;
2120 PyObject *return_value;
2121
2122 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002123 path.function_name = "stat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002124 path.allow_fd = 1;
2125 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2126 path_converter, &path,
2127#ifdef HAVE_FSTATAT
2128 dir_fd_converter, &dir_fd,
2129#else
2130 dir_fd_unavailable, &dir_fd,
2131#endif
2132 &follow_symlinks))
2133 return NULL;
2134 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2135 path_cleanup(&path);
2136 return return_value;
2137}
2138
2139PyDoc_STRVAR(posix_lstat__doc__,
2140"lstat(path, *, dir_fd=None) -> stat result\n\n\
2141Like stat(), but do not follow symbolic links.\n\
2142Equivalent to stat(path, follow_symlinks=False).");
2143
2144static PyObject *
2145posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2146{
2147 static char *keywords[] = {"path", "dir_fd", NULL};
2148 path_t path;
2149 int dir_fd = DEFAULT_DIR_FD;
2150 int follow_symlinks = 0;
2151 PyObject *return_value;
2152
2153 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002154 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002155 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2156 path_converter, &path,
2157#ifdef HAVE_FSTATAT
2158 dir_fd_converter, &dir_fd
2159#else
2160 dir_fd_unavailable, &dir_fd
2161#endif
2162 ))
2163 return NULL;
2164 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2165 path_cleanup(&path);
2166 return return_value;
2167}
2168
2169PyDoc_STRVAR(posix_access__doc__,
2170"access(path, mode, *, dir_fd=None, effective_ids=False,\
2171 follow_symlinks=True)\n\n\
2172Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2173False otherwise.\n\
2174\n\
2175If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2176 and path should be relative; path will then be relative to that directory.\n\
2177If effective_ids is True, access will use the effective uid/gid instead of\n\
2178 the real uid/gid.\n\
2179If follow_symlinks is False, and the last element of the path is a symbolic\n\
2180 link, access will examine the symbolic link itself instead of the file the\n\
2181 link points to.\n\
2182dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2183 on your platform. If they are unavailable, using them will raise a\n\
2184 NotImplementedError.\n\
2185\n\
2186Note that most operations will use the effective uid/gid, therefore this\n\
2187 routine can be used in a suid/sgid environment to test if the invoking user\n\
2188 has the specified access to the path.\n\
2189The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2190 of R_OK, W_OK, and X_OK.");
2191
2192static PyObject *
2193posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2194{
2195 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2196 "follow_symlinks", NULL};
2197 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002198 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002199 int dir_fd = DEFAULT_DIR_FD;
2200 int effective_ids = 0;
2201 int follow_symlinks = 1;
2202 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002203
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002204#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002205 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002206#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002207 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002208#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002209
2210 memset(&path, 0, sizeof(path));
2211 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2212 path_converter, &path, &mode,
2213#ifdef HAVE_FACCESSAT
2214 dir_fd_converter, &dir_fd,
2215#else
2216 dir_fd_unavailable, &dir_fd,
2217#endif
2218 &effective_ids, &follow_symlinks))
2219 return NULL;
2220
2221#ifndef HAVE_FACCESSAT
2222 if (follow_symlinks_specified("access", follow_symlinks))
2223 goto exit;
2224
2225 if (effective_ids) {
2226 argument_unavailable_error("access", "effective_ids");
2227 goto exit;
2228 }
2229#endif
2230
2231#ifdef MS_WINDOWS
2232 Py_BEGIN_ALLOW_THREADS
2233 if (path.wide != NULL)
2234 attr = GetFileAttributesW(path.wide);
2235 else
2236 attr = GetFileAttributesA(path.narrow);
2237 Py_END_ALLOW_THREADS
2238
2239 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002240 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002241 * * we didn't get a -1, and
2242 * * write access wasn't requested,
2243 * * or the file isn't read-only,
2244 * * or it's a directory.
2245 * (Directories cannot be read-only on Windows.)
2246 */
2247 return_value = PyBool_FromLong(
2248 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002249 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002250 !(attr & FILE_ATTRIBUTE_READONLY) ||
2251 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2252#else
2253
2254 Py_BEGIN_ALLOW_THREADS
2255#ifdef HAVE_FACCESSAT
2256 if ((dir_fd != DEFAULT_DIR_FD) ||
2257 effective_ids ||
2258 !follow_symlinks) {
2259 int flags = 0;
2260 if (!follow_symlinks)
2261 flags |= AT_SYMLINK_NOFOLLOW;
2262 if (effective_ids)
2263 flags |= AT_EACCESS;
2264 result = faccessat(dir_fd, path.narrow, mode, flags);
2265 }
2266 else
2267#endif
2268 result = access(path.narrow, mode);
2269 Py_END_ALLOW_THREADS
2270 return_value = PyBool_FromLong(!result);
2271#endif
2272
2273#ifndef HAVE_FACCESSAT
2274exit:
2275#endif
2276 path_cleanup(&path);
2277 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002278}
2279
Guido van Rossumd371ff11999-01-25 16:12:23 +00002280#ifndef F_OK
2281#define F_OK 0
2282#endif
2283#ifndef R_OK
2284#define R_OK 4
2285#endif
2286#ifndef W_OK
2287#define W_OK 2
2288#endif
2289#ifndef X_OK
2290#define X_OK 1
2291#endif
2292
2293#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002294PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002295"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002296Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002297
2298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002299posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002300{
Victor Stinner8c62be82010-05-06 00:08:46 +00002301 int id;
2302 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002303
Victor Stinner8c62be82010-05-06 00:08:46 +00002304 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2305 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002306
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002307#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002308 /* file descriptor 0 only, the default input device (stdin) */
2309 if (id == 0) {
2310 ret = ttyname();
2311 }
2312 else {
2313 ret = NULL;
2314 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002315#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002316 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002317#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002318 if (ret == NULL)
2319 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002320 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002321}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002322#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002323
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002324#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002325PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002326"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002327Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002328
2329static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002330posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002331{
Victor Stinner8c62be82010-05-06 00:08:46 +00002332 char *ret;
2333 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002334
Greg Wardb48bc172000-03-01 21:51:56 +00002335#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002336 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002337#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002338 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002339#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002340 if (ret == NULL)
2341 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002342 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002343}
2344#endif
2345
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002346PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002347"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002348Change the current working directory to the specified path.\n\
2349\n\
2350path may always be specified as a string.\n\
2351On some platforms, path may also be specified as an open file descriptor.\n\
2352 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002353
Barry Warsaw53699e91996-12-10 23:23:01 +00002354static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002355posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002356{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002357 path_t path;
2358 int result;
2359 PyObject *return_value = NULL;
2360 static char *keywords[] = {"path", NULL};
2361
2362 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002363 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002364#ifdef HAVE_FCHDIR
2365 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002366#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002367 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2368 path_converter, &path
2369 ))
2370 return NULL;
2371
2372 Py_BEGIN_ALLOW_THREADS
2373#ifdef MS_WINDOWS
2374 if (path.wide)
2375 result = win32_wchdir(path.wide);
2376 else
2377 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002378 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002379#else
2380#ifdef HAVE_FCHDIR
2381 if (path.fd != -1)
2382 result = fchdir(path.fd);
2383 else
2384#endif
2385 result = chdir(path.narrow);
2386#endif
2387 Py_END_ALLOW_THREADS
2388
2389 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002390 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002391 goto exit;
2392 }
2393
2394 return_value = Py_None;
2395 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002396
Larry Hastings9cf065c2012-06-22 16:30:09 -07002397exit:
2398 path_cleanup(&path);
2399 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002400}
2401
Fred Drake4d1e64b2002-04-15 19:40:07 +00002402#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002403PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002404"fchdir(fd)\n\n\
2405Change to the directory of the given file descriptor. fd must be\n\
2406opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002407
2408static PyObject *
2409posix_fchdir(PyObject *self, PyObject *fdobj)
2410{
Victor Stinner8c62be82010-05-06 00:08:46 +00002411 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002412}
2413#endif /* HAVE_FCHDIR */
2414
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002415
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002416PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002417"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2418Change the access permissions of a file.\n\
2419\n\
2420path may always be specified as a string.\n\
2421On some platforms, path may also be specified as an open file descriptor.\n\
2422 If this functionality is unavailable, using it raises an exception.\n\
2423If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2424 and path should be relative; path will then be relative to that directory.\n\
2425If follow_symlinks is False, and the last element of the path is a symbolic\n\
2426 link, chmod will modify the symbolic link itself instead of the file the\n\
2427 link points to.\n\
2428It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2429 an open file descriptor.\n\
2430dir_fd and follow_symlinks may not be implemented on your platform.\n\
2431 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002432
Barry Warsaw53699e91996-12-10 23:23:01 +00002433static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002434posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002435{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002436 path_t path;
2437 int mode;
2438 int dir_fd = DEFAULT_DIR_FD;
2439 int follow_symlinks = 1;
2440 int result;
2441 PyObject *return_value = NULL;
2442 static char *keywords[] = {"path", "mode", "dir_fd",
2443 "follow_symlinks", NULL};
2444
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002445#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002446 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002447#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002448
Larry Hastings9cf065c2012-06-22 16:30:09 -07002449#ifdef HAVE_FCHMODAT
2450 int fchmodat_nofollow_unsupported = 0;
2451#endif
2452
2453 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002454 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002455#ifdef HAVE_FCHMOD
2456 path.allow_fd = 1;
2457#endif
2458 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2459 path_converter, &path,
2460 &mode,
2461#ifdef HAVE_FCHMODAT
2462 dir_fd_converter, &dir_fd,
2463#else
2464 dir_fd_unavailable, &dir_fd,
2465#endif
2466 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002467 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002468
2469#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2470 if (follow_symlinks_specified("chmod", follow_symlinks))
2471 goto exit;
2472#endif
2473
2474#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002475 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002476 if (path.wide)
2477 attr = GetFileAttributesW(path.wide);
2478 else
2479 attr = GetFileAttributesA(path.narrow);
2480 if (attr == 0xFFFFFFFF)
2481 result = 0;
2482 else {
2483 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002484 attr &= ~FILE_ATTRIBUTE_READONLY;
2485 else
2486 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002487 if (path.wide)
2488 result = SetFileAttributesW(path.wide, attr);
2489 else
2490 result = SetFileAttributesA(path.narrow, attr);
2491 }
2492 Py_END_ALLOW_THREADS
2493
2494 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002495 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002496 goto exit;
2497 }
2498#else /* MS_WINDOWS */
2499 Py_BEGIN_ALLOW_THREADS
2500#ifdef HAVE_FCHMOD
2501 if (path.fd != -1)
2502 result = fchmod(path.fd, mode);
2503 else
2504#endif
2505#ifdef HAVE_LCHMOD
2506 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2507 result = lchmod(path.narrow, mode);
2508 else
2509#endif
2510#ifdef HAVE_FCHMODAT
2511 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2512 /*
2513 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2514 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002515 * and then says it isn't implemented yet.
2516 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002517 *
2518 * Once it is supported, os.chmod will automatically
2519 * support dir_fd and follow_symlinks=False. (Hopefully.)
2520 * Until then, we need to be careful what exception we raise.
2521 */
2522 result = fchmodat(dir_fd, path.narrow, mode,
2523 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2524 /*
2525 * But wait! We can't throw the exception without allowing threads,
2526 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2527 */
2528 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002529 result &&
2530 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2531 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002532 }
2533 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002534#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002535 result = chmod(path.narrow, mode);
2536 Py_END_ALLOW_THREADS
2537
2538 if (result) {
2539#ifdef HAVE_FCHMODAT
2540 if (fchmodat_nofollow_unsupported) {
2541 if (dir_fd != DEFAULT_DIR_FD)
2542 dir_fd_and_follow_symlinks_invalid("chmod",
2543 dir_fd, follow_symlinks);
2544 else
2545 follow_symlinks_specified("chmod", follow_symlinks);
2546 }
2547 else
2548#endif
Victor Stinner292c8352012-10-30 02:17:38 +01002549 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002550 goto exit;
2551 }
2552#endif
2553
2554 Py_INCREF(Py_None);
2555 return_value = Py_None;
2556exit:
2557 path_cleanup(&path);
2558 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002559}
2560
Larry Hastings9cf065c2012-06-22 16:30:09 -07002561
Christian Heimes4e30a842007-11-30 22:12:06 +00002562#ifdef HAVE_FCHMOD
2563PyDoc_STRVAR(posix_fchmod__doc__,
2564"fchmod(fd, mode)\n\n\
2565Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002566descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002567
2568static PyObject *
2569posix_fchmod(PyObject *self, PyObject *args)
2570{
Victor Stinner8c62be82010-05-06 00:08:46 +00002571 int fd, mode, res;
2572 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2573 return NULL;
2574 Py_BEGIN_ALLOW_THREADS
2575 res = fchmod(fd, mode);
2576 Py_END_ALLOW_THREADS
2577 if (res < 0)
2578 return posix_error();
2579 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002580}
2581#endif /* HAVE_FCHMOD */
2582
2583#ifdef HAVE_LCHMOD
2584PyDoc_STRVAR(posix_lchmod__doc__,
2585"lchmod(path, mode)\n\n\
2586Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002587affects the link itself rather than the target.\n\
2588Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002589
2590static PyObject *
2591posix_lchmod(PyObject *self, PyObject *args)
2592{
Victor Stinner292c8352012-10-30 02:17:38 +01002593 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002594 int i;
2595 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002596 memset(&path, 0, sizeof(path));
2597 path.function_name = "lchmod";
2598 if (!PyArg_ParseTuple(args, "O&i:lchmod",
2599 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002600 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002601 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002602 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00002603 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002604 if (res < 0) {
2605 path_error(&path);
2606 path_cleanup(&path);
2607 return NULL;
2608 }
2609 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002610 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002611}
2612#endif /* HAVE_LCHMOD */
2613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002614
Thomas Wouterscf297e42007-02-23 15:07:44 +00002615#ifdef HAVE_CHFLAGS
2616PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002617"chflags(path, flags, *, follow_symlinks=True)\n\n\
2618Set file flags.\n\
2619\n\
2620If follow_symlinks is False, and the last element of the path is a symbolic\n\
2621 link, chflags will change flags on the symbolic link itself instead of the\n\
2622 file the link points to.\n\
2623follow_symlinks may not be implemented on your platform. If it is\n\
2624unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002625
2626static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002628{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002629 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002630 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002631 int follow_symlinks = 1;
2632 int result;
2633 PyObject *return_value;
2634 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2635
2636 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002637 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002638 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2639 path_converter, &path,
2640 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002641 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002642
2643#ifndef HAVE_LCHFLAGS
2644 if (follow_symlinks_specified("chflags", follow_symlinks))
2645 goto exit;
2646#endif
2647
Victor Stinner8c62be82010-05-06 00:08:46 +00002648 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002649#ifdef HAVE_LCHFLAGS
2650 if (!follow_symlinks)
2651 result = lchflags(path.narrow, flags);
2652 else
2653#endif
2654 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002655 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002656
2657 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002658 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002659 goto exit;
2660 }
2661
2662 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002663 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002664
2665exit:
2666 path_cleanup(&path);
2667 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002668}
2669#endif /* HAVE_CHFLAGS */
2670
2671#ifdef HAVE_LCHFLAGS
2672PyDoc_STRVAR(posix_lchflags__doc__,
2673"lchflags(path, flags)\n\n\
2674Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002675This function will not follow symbolic links.\n\
2676Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002677
2678static PyObject *
2679posix_lchflags(PyObject *self, PyObject *args)
2680{
Victor Stinner292c8352012-10-30 02:17:38 +01002681 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002682 unsigned long flags;
2683 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002684 memset(&path, 0, sizeof(path));
2685 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00002686 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01002687 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00002688 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002689 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002690 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002691 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002692 if (res < 0) {
2693 path_error(&path);
2694 path_cleanup(&path);
2695 return NULL;
2696 }
2697 path_cleanup(&path);
2698 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002699}
2700#endif /* HAVE_LCHFLAGS */
2701
Martin v. Löwis244edc82001-10-04 22:44:26 +00002702#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002703PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002704"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002705Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002706
2707static PyObject *
2708posix_chroot(PyObject *self, PyObject *args)
2709{
Victor Stinner292c8352012-10-30 02:17:38 +01002710 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002711}
2712#endif
2713
Guido van Rossum21142a01999-01-08 21:05:37 +00002714#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002715PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002716"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002717force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002718
2719static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002720posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002721{
Stefan Krah0e803b32010-11-26 16:16:47 +00002722 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002723}
2724#endif /* HAVE_FSYNC */
2725
Ross Lagerwall7807c352011-03-17 20:20:30 +02002726#ifdef HAVE_SYNC
2727PyDoc_STRVAR(posix_sync__doc__,
2728"sync()\n\n\
2729Force write of everything to disk.");
2730
2731static PyObject *
2732posix_sync(PyObject *self, PyObject *noargs)
2733{
2734 Py_BEGIN_ALLOW_THREADS
2735 sync();
2736 Py_END_ALLOW_THREADS
2737 Py_RETURN_NONE;
2738}
2739#endif
2740
Guido van Rossum21142a01999-01-08 21:05:37 +00002741#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002742
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002743#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002744extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2745#endif
2746
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002747PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002748"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002749force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002750 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002751
2752static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002753posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002754{
Stefan Krah0e803b32010-11-26 16:16:47 +00002755 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002756}
2757#endif /* HAVE_FDATASYNC */
2758
2759
Fredrik Lundh10723342000-07-10 16:38:09 +00002760#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002761PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002762"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2763Change the owner and group id of path to the numeric uid and gid.\n\
2764\n\
2765path may always be specified as a string.\n\
2766On some platforms, path may also be specified as an open file descriptor.\n\
2767 If this functionality is unavailable, using it raises an exception.\n\
2768If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2769 and path should be relative; path will then be relative to that directory.\n\
2770If follow_symlinks is False, and the last element of the path is a symbolic\n\
2771 link, chown will modify the symbolic link itself instead of the file the\n\
2772 link points to.\n\
2773It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2774 an open file descriptor.\n\
2775dir_fd and follow_symlinks may not be implemented on your platform.\n\
2776 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002777
Barry Warsaw53699e91996-12-10 23:23:01 +00002778static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002779posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002780{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002781 path_t path;
2782 long uid_l, gid_l;
2783 uid_t uid;
2784 gid_t gid;
2785 int dir_fd = DEFAULT_DIR_FD;
2786 int follow_symlinks = 1;
2787 int result;
2788 PyObject *return_value = NULL;
2789 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2790 "follow_symlinks", NULL};
2791
2792 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002793 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002794#ifdef HAVE_FCHOWN
2795 path.allow_fd = 1;
2796#endif
2797 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2798 path_converter, &path,
2799 &uid_l, &gid_l,
2800#ifdef HAVE_FCHOWNAT
2801 dir_fd_converter, &dir_fd,
2802#else
2803 dir_fd_unavailable, &dir_fd,
2804#endif
2805 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002806 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807
2808#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2809 if (follow_symlinks_specified("chown", follow_symlinks))
2810 goto exit;
2811#endif
2812 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2813 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2814 goto exit;
2815
2816#ifdef __APPLE__
2817 /*
2818 * This is for Mac OS X 10.3, which doesn't have lchown.
2819 * (But we still have an lchown symbol because of weak-linking.)
2820 * It doesn't have fchownat either. So there's no possibility
2821 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02002822 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002823 if ((!follow_symlinks) && (lchown == NULL)) {
2824 follow_symlinks_specified("chown", follow_symlinks);
2825 goto exit;
2826 }
2827#endif
2828
Victor Stinner8c62be82010-05-06 00:08:46 +00002829 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002830 uid = (uid_t)uid_l;
2831 gid = (uid_t)gid_l;
2832#ifdef HAVE_FCHOWN
2833 if (path.fd != -1)
2834 result = fchown(path.fd, uid, gid);
2835 else
2836#endif
2837#ifdef HAVE_LCHOWN
2838 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2839 result = lchown(path.narrow, uid, gid);
2840 else
2841#endif
2842#ifdef HAVE_FCHOWNAT
2843 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
2844 result = fchownat(dir_fd, path.narrow, uid, gid,
2845 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2846 else
2847#endif
2848 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002849 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002850
2851 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002852 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002853 goto exit;
2854 }
2855
2856 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002858
2859exit:
2860 path_cleanup(&path);
2861 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002862}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002863#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002864
Christian Heimes4e30a842007-11-30 22:12:06 +00002865#ifdef HAVE_FCHOWN
2866PyDoc_STRVAR(posix_fchown__doc__,
2867"fchown(fd, uid, gid)\n\n\
2868Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002869fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002870
2871static PyObject *
2872posix_fchown(PyObject *self, PyObject *args)
2873{
Victor Stinner8c62be82010-05-06 00:08:46 +00002874 int fd;
2875 long uid, gid;
2876 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002877 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002878 return NULL;
2879 Py_BEGIN_ALLOW_THREADS
2880 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2881 Py_END_ALLOW_THREADS
2882 if (res < 0)
2883 return posix_error();
2884 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002885}
2886#endif /* HAVE_FCHOWN */
2887
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002888#ifdef HAVE_LCHOWN
2889PyDoc_STRVAR(posix_lchown__doc__,
2890"lchown(path, uid, gid)\n\n\
2891Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002892This function will not follow symbolic links.\n\
2893Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002894
2895static PyObject *
2896posix_lchown(PyObject *self, PyObject *args)
2897{
Victor Stinner292c8352012-10-30 02:17:38 +01002898 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 long uid, gid;
2900 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002901 memset(&path, 0, sizeof(path));
2902 path.function_name = "lchown";
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 if (!PyArg_ParseTuple(args, "O&ll:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01002904 path_converter, &path,
Victor Stinner8c62be82010-05-06 00:08:46 +00002905 &uid, &gid))
2906 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002907 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002908 res = lchown(path.narrow, (uid_t) uid, (gid_t) gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002909 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002910 if (res < 0) {
2911 path_error(&path);
2912 path_cleanup(&path);
2913 return NULL;
2914 }
2915 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 Py_INCREF(Py_None);
2917 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002918}
2919#endif /* HAVE_LCHOWN */
2920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002921
Guido van Rossum36bc6801995-06-14 22:54:23 +00002922#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002923static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002924posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002925{
Victor Stinner8c62be82010-05-06 00:08:46 +00002926 char buf[1026];
2927 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002928
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002929#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002930 if (!use_bytes) {
2931 wchar_t wbuf[1026];
2932 wchar_t *wbuf2 = wbuf;
2933 PyObject *resobj;
2934 DWORD len;
2935 Py_BEGIN_ALLOW_THREADS
2936 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2937 /* If the buffer is large enough, len does not include the
2938 terminating \0. If the buffer is too small, len includes
2939 the space needed for the terminator. */
2940 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2941 wbuf2 = malloc(len * sizeof(wchar_t));
2942 if (wbuf2)
2943 len = GetCurrentDirectoryW(len, wbuf2);
2944 }
2945 Py_END_ALLOW_THREADS
2946 if (!wbuf2) {
2947 PyErr_NoMemory();
2948 return NULL;
2949 }
2950 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002951 if (wbuf2 != wbuf)
2952 free(wbuf2);
2953 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00002954 }
2955 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01002956 if (wbuf2 != wbuf)
2957 free(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00002958 return resobj;
2959 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01002960
2961 if (win32_warn_bytes_api())
2962 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002963#endif
2964
Victor Stinner8c62be82010-05-06 00:08:46 +00002965 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002966 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00002967 Py_END_ALLOW_THREADS
2968 if (res == NULL)
2969 return posix_error();
2970 if (use_bytes)
2971 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002972 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002973}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002974
2975PyDoc_STRVAR(posix_getcwd__doc__,
2976"getcwd() -> path\n\n\
2977Return a unicode string representing the current working directory.");
2978
2979static PyObject *
2980posix_getcwd_unicode(PyObject *self)
2981{
2982 return posix_getcwd(0);
2983}
2984
2985PyDoc_STRVAR(posix_getcwdb__doc__,
2986"getcwdb() -> path\n\n\
2987Return a bytes string representing the current working directory.");
2988
2989static PyObject *
2990posix_getcwd_bytes(PyObject *self)
2991{
2992 return posix_getcwd(1);
2993}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002994#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002995
Larry Hastings9cf065c2012-06-22 16:30:09 -07002996#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
2997#define HAVE_LINK 1
2998#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002999
Guido van Rossumb6775db1994-08-01 11:34:53 +00003000#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003001PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003002"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3003Create a hard link to a file.\n\
3004\n\
3005If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3006 descriptor open to a directory, and the respective path string (src or dst)\n\
3007 should be relative; the path will then be relative to that directory.\n\
3008If follow_symlinks is False, and the last element of src is a symbolic\n\
3009 link, link will create a link to the symbolic link itself instead of the\n\
3010 file the link points to.\n\
3011src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3012 platform. If they are unavailable, using them will raise a\n\
3013 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014
Barry Warsaw53699e91996-12-10 23:23:01 +00003015static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003016posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003017{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003018 path_t src, dst;
3019 int src_dir_fd = DEFAULT_DIR_FD;
3020 int dst_dir_fd = DEFAULT_DIR_FD;
3021 int follow_symlinks = 1;
3022 PyObject *return_value = NULL;
3023 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3024 "follow_symlinks", NULL};
3025#ifdef MS_WINDOWS
3026 BOOL result;
3027#else
3028 int result;
3029#endif
3030
3031 memset(&src, 0, sizeof(src));
3032 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003033 src.function_name = "link";
3034 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003035 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3036 path_converter, &src,
3037 path_converter, &dst,
3038 dir_fd_converter, &src_dir_fd,
3039 dir_fd_converter, &dst_dir_fd,
3040 &follow_symlinks))
3041 return NULL;
3042
3043#ifndef HAVE_LINKAT
3044 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3045 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3046 goto exit;
3047 }
3048#endif
3049
3050 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3051 PyErr_SetString(PyExc_NotImplementedError,
3052 "link: src and dst must be the same type");
3053 goto exit;
3054 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003055
Brian Curtin1b9df392010-11-24 20:24:31 +00003056#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003057 Py_BEGIN_ALLOW_THREADS
3058 if (src.wide)
3059 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3060 else
3061 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3062 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003063
Larry Hastings9cf065c2012-06-22 16:30:09 -07003064 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003065 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003066 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003067 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003068#else
3069 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003070#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003071 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3072 (dst_dir_fd != DEFAULT_DIR_FD) ||
3073 (!follow_symlinks))
3074 result = linkat(src_dir_fd, src.narrow,
3075 dst_dir_fd, dst.narrow,
3076 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3077 else
3078#endif
3079 result = link(src.narrow, dst.narrow);
3080 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003081
Larry Hastings9cf065c2012-06-22 16:30:09 -07003082 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003083 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003084 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003085 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003086#endif
3087
3088 return_value = Py_None;
3089 Py_INCREF(Py_None);
3090
3091exit:
3092 path_cleanup(&src);
3093 path_cleanup(&dst);
3094 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003095}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003096#endif
3097
Brian Curtin1b9df392010-11-24 20:24:31 +00003098
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003099
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003100PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003101"listdir(path='.') -> list_of_filenames\n\n\
3102Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003103The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003104entries '.' and '..' even if they are present in the directory.\n\
3105\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003106path can be specified as either str or bytes. If path is bytes,\n\
3107 the filenames returned will also be bytes; in all other circumstances\n\
3108 the filenames returned will be str.\n\
3109On some platforms, path may also be specified as an open file descriptor;\n\
3110 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003111 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003112
Barry Warsaw53699e91996-12-10 23:23:01 +00003113static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003114posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003115{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003116 path_t path;
3117 PyObject *list = NULL;
3118 static char *keywords[] = {"path", NULL};
3119 int fd = -1;
3120
3121#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3122 PyObject *v;
3123 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3124 BOOL result;
3125 WIN32_FIND_DATA FileData;
3126 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3127 char *bufptr = namebuf;
3128 /* only claim to have space for MAX_PATH */
3129 Py_ssize_t len = sizeof(namebuf)-5;
3130 PyObject *po = NULL;
3131 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003132#else
3133 PyObject *v;
3134 DIR *dirp = NULL;
3135 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003136 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003137#endif
3138
3139 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003140 path.function_name = "listdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003141 path.nullable = 1;
3142#ifdef HAVE_FDOPENDIR
3143 path.allow_fd = 1;
3144 path.fd = -1;
3145#endif
3146 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3147 path_converter, &path
3148 ))
3149 return NULL;
3150
Victor Stinner8c62be82010-05-06 00:08:46 +00003151 /* XXX Should redo this putting the (now four) versions of opendir
3152 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003153#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003154 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003157
Larry Hastings9cf065c2012-06-22 16:30:09 -07003158 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003159 po_wchars = L".";
3160 len = 1;
3161 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003162 po_wchars = path.wide;
3163 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003164 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003165 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003166 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3167 if (!wnamebuf) {
3168 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003170 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003171 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003172 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003173 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003174 if (wch != L'/' && wch != L'\\' && wch != L':')
3175 wnamebuf[len++] = L'\\';
3176 wcscpy(wnamebuf + len, L"*.*");
3177 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003178 if ((list = PyList_New(0)) == NULL) {
3179 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003180 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003181 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003183 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003184 if (hFindFile == INVALID_HANDLE_VALUE) {
3185 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003186 if (error == ERROR_FILE_NOT_FOUND)
3187 goto exit;
3188 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003189 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003190 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003191 }
3192 do {
3193 /* Skip over . and .. */
3194 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3195 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003196 v = PyUnicode_FromWideChar(wFileData.cFileName,
3197 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003199 Py_DECREF(list);
3200 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003201 break;
3202 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003204 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003205 Py_DECREF(list);
3206 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003207 break;
3208 }
3209 Py_DECREF(v);
3210 }
3211 Py_BEGIN_ALLOW_THREADS
3212 result = FindNextFileW(hFindFile, &wFileData);
3213 Py_END_ALLOW_THREADS
3214 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3215 it got to the end of the directory. */
3216 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003217 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003218 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003219 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003220 }
3221 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003222
Larry Hastings9cf065c2012-06-22 16:30:09 -07003223 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003225 strcpy(namebuf, path.narrow);
3226 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003227 if (len > 0) {
3228 char ch = namebuf[len-1];
3229 if (ch != SEP && ch != ALTSEP && ch != ':')
3230 namebuf[len++] = '/';
3231 strcpy(namebuf + len, "*.*");
3232 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003233
Larry Hastings9cf065c2012-06-22 16:30:09 -07003234 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003236
Antoine Pitroub73caab2010-08-09 23:39:31 +00003237 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003238 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003239 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 if (hFindFile == INVALID_HANDLE_VALUE) {
3241 int error = GetLastError();
3242 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003243 goto exit;
3244 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003245 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003246 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003247 }
3248 do {
3249 /* Skip over . and .. */
3250 if (strcmp(FileData.cFileName, ".") != 0 &&
3251 strcmp(FileData.cFileName, "..") != 0) {
3252 v = PyBytes_FromString(FileData.cFileName);
3253 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003254 Py_DECREF(list);
3255 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 break;
3257 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003258 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003260 Py_DECREF(list);
3261 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003262 break;
3263 }
3264 Py_DECREF(v);
3265 }
3266 Py_BEGIN_ALLOW_THREADS
3267 result = FindNextFile(hFindFile, &FileData);
3268 Py_END_ALLOW_THREADS
3269 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3270 it got to the end of the directory. */
3271 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003272 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003273 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003274 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003275 }
3276 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003277
Larry Hastings9cf065c2012-06-22 16:30:09 -07003278exit:
3279 if (hFindFile != INVALID_HANDLE_VALUE) {
3280 if (FindClose(hFindFile) == FALSE) {
3281 if (list != NULL) {
3282 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003283 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003284 }
3285 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003287 if (wnamebuf)
3288 free(wnamebuf);
3289 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003290
Larry Hastings9cf065c2012-06-22 16:30:09 -07003291 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003292
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003293#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003294
Victor Stinner8c62be82010-05-06 00:08:46 +00003295 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003296#ifdef HAVE_FDOPENDIR
3297 if (path.fd != -1) {
3298 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003299 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003300 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003301 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003302
3303 if (fd == -1) {
3304 list = posix_error();
3305 goto exit;
3306 }
3307
Larry Hastingsfdaea062012-06-25 04:42:23 -07003308 return_str = 1;
3309
Larry Hastings9cf065c2012-06-22 16:30:09 -07003310 Py_BEGIN_ALLOW_THREADS
3311 dirp = fdopendir(fd);
3312 Py_END_ALLOW_THREADS
3313 }
3314 else
3315#endif
3316 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003317 char *name;
3318 if (path.narrow) {
3319 name = path.narrow;
3320 /* only return bytes if they specified a bytes object */
3321 return_str = !(PyBytes_Check(path.object));
3322 }
3323 else {
3324 name = ".";
3325 return_str = 1;
3326 }
3327
Larry Hastings9cf065c2012-06-22 16:30:09 -07003328 Py_BEGIN_ALLOW_THREADS
3329 dirp = opendir(name);
3330 Py_END_ALLOW_THREADS
3331 }
3332
3333 if (dirp == NULL) {
Victor Stinner292c8352012-10-30 02:17:38 +01003334 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003335 goto exit;
3336 }
3337 if ((list = PyList_New(0)) == NULL) {
3338 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003339 }
3340 for (;;) {
3341 errno = 0;
3342 Py_BEGIN_ALLOW_THREADS
3343 ep = readdir(dirp);
3344 Py_END_ALLOW_THREADS
3345 if (ep == NULL) {
3346 if (errno == 0) {
3347 break;
3348 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003349 Py_DECREF(list);
Victor Stinner292c8352012-10-30 02:17:38 +01003350 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003351 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003352 }
3353 }
3354 if (ep->d_name[0] == '.' &&
3355 (NAMLEN(ep) == 1 ||
3356 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3357 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003358 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003359 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3360 else
3361 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003363 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 break;
3365 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003366 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003367 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003369 break;
3370 }
3371 Py_DECREF(v);
3372 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003373
Larry Hastings9cf065c2012-06-22 16:30:09 -07003374exit:
3375 if (dirp != NULL) {
3376 Py_BEGIN_ALLOW_THREADS
3377 if (fd > -1)
3378 rewinddir(dirp);
3379 closedir(dirp);
3380 Py_END_ALLOW_THREADS
3381 }
3382
3383 path_cleanup(&path);
3384
3385 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003386
Tim Peters0bb44a42000-09-15 07:44:49 +00003387#endif /* which OS */
3388} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003389
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003390#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003391/* A helper function for abspath on win32 */
3392static PyObject *
3393posix__getfullpathname(PyObject *self, PyObject *args)
3394{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003395 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003396 char outbuf[MAX_PATH*2];
3397 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003398 PyObject *po;
3399
3400 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3401 {
3402 wchar_t *wpath;
3403 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3404 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 DWORD result;
3406 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003407
3408 wpath = PyUnicode_AsUnicode(po);
3409 if (wpath == NULL)
3410 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003411 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003412 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003413 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003414 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003415 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 if (!woutbufp)
3417 return PyErr_NoMemory();
3418 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3419 }
3420 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003421 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003422 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003423 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003424 if (woutbufp != woutbuf)
3425 free(woutbufp);
3426 return v;
3427 }
3428 /* Drop the argument parsing error as narrow strings
3429 are also valid. */
3430 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003431
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003432 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3433 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003434 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003435 if (win32_warn_bytes_api())
3436 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003437 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003438 outbuf, &temp)) {
3439 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 return NULL;
3441 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3443 return PyUnicode_Decode(outbuf, strlen(outbuf),
3444 Py_FileSystemDefaultEncoding, NULL);
3445 }
3446 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003447} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003448
Brian Curtind25aef52011-06-13 15:16:04 -05003449
Brian Curtinf5e76d02010-11-24 13:14:05 +00003450
Brian Curtind40e6f72010-07-08 21:39:08 +00003451/* A helper function for samepath on windows */
3452static PyObject *
3453posix__getfinalpathname(PyObject *self, PyObject *args)
3454{
3455 HANDLE hFile;
3456 int buf_size;
3457 wchar_t *target_path;
3458 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003459 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003460 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003461
Victor Stinnereb5657a2011-09-30 01:44:27 +02003462 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003463 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003464 path = PyUnicode_AsUnicode(po);
3465 if (path == NULL)
3466 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003467
3468 if(!check_GetFinalPathNameByHandle()) {
3469 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3470 NotImplementedError. */
3471 return PyErr_Format(PyExc_NotImplementedError,
3472 "GetFinalPathNameByHandle not available on this platform");
3473 }
3474
3475 hFile = CreateFileW(
3476 path,
3477 0, /* desired access */
3478 0, /* share mode */
3479 NULL, /* security attributes */
3480 OPEN_EXISTING,
3481 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3482 FILE_FLAG_BACKUP_SEMANTICS,
3483 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003484
Victor Stinnereb5657a2011-09-30 01:44:27 +02003485 if(hFile == INVALID_HANDLE_VALUE)
3486 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003487
3488 /* We have a good handle to the target, use it to determine the
3489 target path name. */
3490 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3491
3492 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003493 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003494
3495 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3496 if(!target_path)
3497 return PyErr_NoMemory();
3498
3499 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3500 buf_size, VOLUME_NAME_DOS);
3501 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003502 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003503
3504 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003505 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003506
3507 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003508 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003509 free(target_path);
3510 return result;
3511
3512} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003513
Brian Curtin95d028f2011-06-09 09:10:38 -05003514PyDoc_STRVAR(posix__isdir__doc__,
3515"Return true if the pathname refers to an existing directory.");
3516
Brian Curtin9c669cc2011-06-08 18:17:18 -05003517static PyObject *
3518posix__isdir(PyObject *self, PyObject *args)
3519{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003520 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003521 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003522 DWORD attributes;
3523
3524 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003525 wchar_t *wpath = PyUnicode_AsUnicode(po);
3526 if (wpath == NULL)
3527 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003528
3529 attributes = GetFileAttributesW(wpath);
3530 if (attributes == INVALID_FILE_ATTRIBUTES)
3531 Py_RETURN_FALSE;
3532 goto check;
3533 }
3534 /* Drop the argument parsing error as narrow strings
3535 are also valid. */
3536 PyErr_Clear();
3537
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003538 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003539 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003540 if (win32_warn_bytes_api())
3541 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003542 attributes = GetFileAttributesA(path);
3543 if (attributes == INVALID_FILE_ATTRIBUTES)
3544 Py_RETURN_FALSE;
3545
3546check:
3547 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3548 Py_RETURN_TRUE;
3549 else
3550 Py_RETURN_FALSE;
3551}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003552#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003553
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003554PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3556Create a directory.\n\
3557\n\
3558If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3559 and path should be relative; path will then be relative to that directory.\n\
3560dir_fd may not be implemented on your platform.\n\
3561 If it is unavailable, using it will raise a NotImplementedError.\n\
3562\n\
3563The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003564
Barry Warsaw53699e91996-12-10 23:23:01 +00003565static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003567{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003568 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003569 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003570 int dir_fd = DEFAULT_DIR_FD;
3571 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3572 PyObject *return_value = NULL;
3573 int result;
3574
3575 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003576 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003577 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3578 path_converter, &path, &mode,
3579#ifdef HAVE_MKDIRAT
3580 dir_fd_converter, &dir_fd
3581#else
3582 dir_fd_unavailable, &dir_fd
3583#endif
3584 ))
3585 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003586
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003587#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003588 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589 if (path.wide)
3590 result = CreateDirectoryW(path.wide, NULL);
3591 else
3592 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003594
Larry Hastings9cf065c2012-06-22 16:30:09 -07003595 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003596 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003597 goto exit;
3598 }
3599#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601#if HAVE_MKDIRAT
3602 if (dir_fd != DEFAULT_DIR_FD)
3603 result = mkdirat(dir_fd, path.narrow, mode);
3604 else
3605#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003606#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003607 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003608#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003610#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003611 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01003613 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003614 goto exit;
3615 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003616#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617 return_value = Py_None;
3618 Py_INCREF(Py_None);
3619exit:
3620 path_cleanup(&path);
3621 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003622}
3623
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003624
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003625/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3626#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003627#include <sys/resource.h>
3628#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003629
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003630
3631#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003632PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003633"nice(inc) -> new_priority\n\n\
3634Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003635
Barry Warsaw53699e91996-12-10 23:23:01 +00003636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003637posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003638{
Victor Stinner8c62be82010-05-06 00:08:46 +00003639 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003640
Victor Stinner8c62be82010-05-06 00:08:46 +00003641 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3642 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003643
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 /* There are two flavours of 'nice': one that returns the new
3645 priority (as required by almost all standards out there) and the
3646 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3647 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003648
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 If we are of the nice family that returns the new priority, we
3650 need to clear errno before the call, and check if errno is filled
3651 before calling posix_error() on a returnvalue of -1, because the
3652 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003653
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 errno = 0;
3655 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003656#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 if (value == 0)
3658 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003659#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 if (value == -1 && errno != 0)
3661 /* either nice() or getpriority() returned an error */
3662 return posix_error();
3663 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003664}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003665#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003666
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003667
3668#ifdef HAVE_GETPRIORITY
3669PyDoc_STRVAR(posix_getpriority__doc__,
3670"getpriority(which, who) -> current_priority\n\n\
3671Get program scheduling priority.");
3672
3673static PyObject *
3674posix_getpriority(PyObject *self, PyObject *args)
3675{
3676 int which, who, retval;
3677
3678 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3679 return NULL;
3680 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003681 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003682 if (errno != 0)
3683 return posix_error();
3684 return PyLong_FromLong((long)retval);
3685}
3686#endif /* HAVE_GETPRIORITY */
3687
3688
3689#ifdef HAVE_SETPRIORITY
3690PyDoc_STRVAR(posix_setpriority__doc__,
3691"setpriority(which, who, prio) -> None\n\n\
3692Set program scheduling priority.");
3693
3694static PyObject *
3695posix_setpriority(PyObject *self, PyObject *args)
3696{
3697 int which, who, prio, retval;
3698
3699 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3700 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003701 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003702 if (retval == -1)
3703 return posix_error();
3704 Py_RETURN_NONE;
3705}
3706#endif /* HAVE_SETPRIORITY */
3707
3708
Barry Warsaw53699e91996-12-10 23:23:01 +00003709static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003711{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003712 char *function_name = is_replace ? "replace" : "rename";
3713 path_t src;
3714 path_t dst;
3715 int src_dir_fd = DEFAULT_DIR_FD;
3716 int dst_dir_fd = DEFAULT_DIR_FD;
3717 int dir_fd_specified;
3718 PyObject *return_value = NULL;
3719 char format[24];
3720 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3721
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003722#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003723 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003724 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003725#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003726 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003727#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728
3729 memset(&src, 0, sizeof(src));
3730 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003731 src.function_name = function_name;
3732 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003733 strcpy(format, "O&O&|$O&O&:");
3734 strcat(format, function_name);
3735 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3736 path_converter, &src,
3737 path_converter, &dst,
3738 dir_fd_converter, &src_dir_fd,
3739 dir_fd_converter, &dst_dir_fd))
3740 return NULL;
3741
3742 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3743 (dst_dir_fd != DEFAULT_DIR_FD);
3744#ifndef HAVE_RENAMEAT
3745 if (dir_fd_specified) {
3746 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
3747 goto exit;
3748 }
3749#endif
3750
3751 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3752 PyErr_Format(PyExc_ValueError,
3753 "%s: src and dst must be the same type", function_name);
3754 goto exit;
3755 }
3756
3757#ifdef MS_WINDOWS
3758 Py_BEGIN_ALLOW_THREADS
3759 if (src.wide)
3760 result = MoveFileExW(src.wide, dst.wide, flags);
3761 else
3762 result = MoveFileExA(src.narrow, dst.narrow, flags);
3763 Py_END_ALLOW_THREADS
3764
3765 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003766 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003767 goto exit;
3768 }
3769
3770#else
3771 Py_BEGIN_ALLOW_THREADS
3772#ifdef HAVE_RENAMEAT
3773 if (dir_fd_specified)
3774 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
3775 else
3776#endif
3777 result = rename(src.narrow, dst.narrow);
3778 Py_END_ALLOW_THREADS
3779
3780 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003781 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003782 goto exit;
3783 }
3784#endif
3785
3786 Py_INCREF(Py_None);
3787 return_value = Py_None;
3788exit:
3789 path_cleanup(&src);
3790 path_cleanup(&dst);
3791 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003792}
3793
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003794PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003795"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3796Rename a file or directory.\n\
3797\n\
3798If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3799 descriptor open to a directory, and the respective path string (src or dst)\n\
3800 should be relative; the path will then be relative to that directory.\n\
3801src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3802 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003803
3804static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003805posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003806{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003807 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003808}
3809
3810PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003811"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3812Rename a file or directory, overwriting the destination.\n\
3813\n\
3814If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3815 descriptor open to a directory, and the respective path string (src or dst)\n\
3816 should be relative; the path will then be relative to that directory.\n\
3817src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3818 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003819
3820static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003821posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003822{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003823 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003824}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003825
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003826PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003827"rmdir(path, *, dir_fd=None)\n\n\
3828Remove a directory.\n\
3829\n\
3830If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3831 and path should be relative; path will then be relative to that directory.\n\
3832dir_fd may not be implemented on your platform.\n\
3833 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003834
Barry Warsaw53699e91996-12-10 23:23:01 +00003835static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003836posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003837{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003838 path_t path;
3839 int dir_fd = DEFAULT_DIR_FD;
3840 static char *keywords[] = {"path", "dir_fd", NULL};
3841 int result;
3842 PyObject *return_value = NULL;
3843
3844 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003845 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003846 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
3847 path_converter, &path,
3848#ifdef HAVE_UNLINKAT
3849 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003850#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003851 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003852#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003853 ))
3854 return NULL;
3855
3856 Py_BEGIN_ALLOW_THREADS
3857#ifdef MS_WINDOWS
3858 if (path.wide)
3859 result = RemoveDirectoryW(path.wide);
3860 else
3861 result = RemoveDirectoryA(path.narrow);
3862 result = !result; /* Windows, success=1, UNIX, success=0 */
3863#else
3864#ifdef HAVE_UNLINKAT
3865 if (dir_fd != DEFAULT_DIR_FD)
3866 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
3867 else
3868#endif
3869 result = rmdir(path.narrow);
3870#endif
3871 Py_END_ALLOW_THREADS
3872
3873 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003874 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003875 goto exit;
3876 }
3877
3878 return_value = Py_None;
3879 Py_INCREF(Py_None);
3880
3881exit:
3882 path_cleanup(&path);
3883 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003884}
3885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003886
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003887#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003888PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003889"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003890Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003891
Barry Warsaw53699e91996-12-10 23:23:01 +00003892static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003893posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003894{
Victor Stinner8c62be82010-05-06 00:08:46 +00003895 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003896#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003897 wchar_t *command;
3898 if (!PyArg_ParseTuple(args, "u:system", &command))
3899 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003900
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 Py_BEGIN_ALLOW_THREADS
3902 sts = _wsystem(command);
3903 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003904#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003905 PyObject *command_obj;
3906 char *command;
3907 if (!PyArg_ParseTuple(args, "O&:system",
3908 PyUnicode_FSConverter, &command_obj))
3909 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003910
Victor Stinner8c62be82010-05-06 00:08:46 +00003911 command = PyBytes_AsString(command_obj);
3912 Py_BEGIN_ALLOW_THREADS
3913 sts = system(command);
3914 Py_END_ALLOW_THREADS
3915 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003916#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003917 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003918}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003919#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003921
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003922PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003923"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003924Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003925
Barry Warsaw53699e91996-12-10 23:23:01 +00003926static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003927posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003928{
Victor Stinner8c62be82010-05-06 00:08:46 +00003929 int i;
3930 if (!PyArg_ParseTuple(args, "i:umask", &i))
3931 return NULL;
3932 i = (int)umask(i);
3933 if (i < 0)
3934 return posix_error();
3935 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003936}
3937
Brian Curtind40e6f72010-07-08 21:39:08 +00003938#ifdef MS_WINDOWS
3939
3940/* override the default DeleteFileW behavior so that directory
3941symlinks can be removed with this function, the same as with
3942Unix symlinks */
3943BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3944{
3945 WIN32_FILE_ATTRIBUTE_DATA info;
3946 WIN32_FIND_DATAW find_data;
3947 HANDLE find_data_handle;
3948 int is_directory = 0;
3949 int is_link = 0;
3950
3951 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3952 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003953
Brian Curtind40e6f72010-07-08 21:39:08 +00003954 /* Get WIN32_FIND_DATA structure for the path to determine if
3955 it is a symlink */
3956 if(is_directory &&
3957 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3958 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3959
3960 if(find_data_handle != INVALID_HANDLE_VALUE) {
3961 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3962 FindClose(find_data_handle);
3963 }
3964 }
3965 }
3966
3967 if (is_directory && is_link)
3968 return RemoveDirectoryW(lpFileName);
3969
3970 return DeleteFileW(lpFileName);
3971}
3972#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003973
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003974PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003975"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003976Remove a file (same as remove()).\n\
3977\n\
3978If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3979 and path should be relative; path will then be relative to that directory.\n\
3980dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003981 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003982
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003983PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003984"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003985Remove a file (same as unlink()).\n\
3986\n\
3987If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3988 and path should be relative; path will then be relative to that directory.\n\
3989dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003990 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003991
Barry Warsaw53699e91996-12-10 23:23:01 +00003992static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003993posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003994{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003995 path_t path;
3996 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003997 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003998 int result;
3999 PyObject *return_value = NULL;
4000
4001 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004002 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004003 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004004 path_converter, &path,
4005#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004006 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004007#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004008 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004009#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004010 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004011 return NULL;
4012
4013 Py_BEGIN_ALLOW_THREADS
4014#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004015 if (path.wide)
4016 result = Py_DeleteFileW(path.wide);
4017 else
4018 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004019 result = !result; /* Windows, success=1, UNIX, success=0 */
4020#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004021#ifdef HAVE_UNLINKAT
4022 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004023 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004024 else
4025#endif /* HAVE_UNLINKAT */
4026 result = unlink(path.narrow);
4027#endif
4028 Py_END_ALLOW_THREADS
4029
4030 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004031 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004032 goto exit;
4033 }
4034
4035 return_value = Py_None;
4036 Py_INCREF(Py_None);
4037
4038exit:
4039 path_cleanup(&path);
4040 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004041}
4042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004043
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004044PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004045"uname() -> uname_result\n\n\
4046Return an object identifying the current operating system.\n\
4047The object behaves like a named tuple with the following fields:\n\
4048 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004049
Larry Hastings605a62d2012-06-24 04:33:36 -07004050static PyStructSequence_Field uname_result_fields[] = {
4051 {"sysname", "operating system name"},
4052 {"nodename", "name of machine on network (implementation-defined)"},
4053 {"release", "operating system release"},
4054 {"version", "operating system version"},
4055 {"machine", "hardware identifier"},
4056 {NULL}
4057};
4058
4059PyDoc_STRVAR(uname_result__doc__,
4060"uname_result: Result from os.uname().\n\n\
4061This object may be accessed either as a tuple of\n\
4062 (sysname, nodename, release, version, machine),\n\
4063or via the attributes sysname, nodename, release, version, and machine.\n\
4064\n\
4065See os.uname for more information.");
4066
4067static PyStructSequence_Desc uname_result_desc = {
4068 "uname_result", /* name */
4069 uname_result__doc__, /* doc */
4070 uname_result_fields,
4071 5
4072};
4073
4074static PyTypeObject UnameResultType;
4075
4076
4077#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004078static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004079posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004080{
Victor Stinner8c62be82010-05-06 00:08:46 +00004081 struct utsname u;
4082 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004083 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004084
Victor Stinner8c62be82010-05-06 00:08:46 +00004085 Py_BEGIN_ALLOW_THREADS
4086 res = uname(&u);
4087 Py_END_ALLOW_THREADS
4088 if (res < 0)
4089 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004090
4091 value = PyStructSequence_New(&UnameResultType);
4092 if (value == NULL)
4093 return NULL;
4094
4095#define SET(i, field) \
4096 { \
4097 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4098 if (!o) { \
4099 Py_DECREF(value); \
4100 return NULL; \
4101 } \
4102 PyStructSequence_SET_ITEM(value, i, o); \
4103 } \
4104
4105 SET(0, u.sysname);
4106 SET(1, u.nodename);
4107 SET(2, u.release);
4108 SET(3, u.version);
4109 SET(4, u.machine);
4110
4111#undef SET
4112
4113 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004114}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004115#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004116
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004117
Larry Hastings9cf065c2012-06-22 16:30:09 -07004118PyDoc_STRVAR(posix_utime__doc__,
4119"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4120Set the access and modified time of path.\n\
4121\n\
4122path may always be specified as a string.\n\
4123On some platforms, path may also be specified as an open file descriptor.\n\
4124 If this functionality is unavailable, using it raises an exception.\n\
4125\n\
4126If times is not None, it must be a tuple (atime, mtime);\n\
4127 atime and mtime should be expressed as float seconds since the epoch.\n\
4128If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4129 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4130 since the epoch.\n\
4131If both times and ns are None, utime uses the current time.\n\
4132Specifying tuples for both times and ns is an error.\n\
4133\n\
4134If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4135 and path should be relative; path will then be relative to that directory.\n\
4136If follow_symlinks is False, and the last element of the path is a symbolic\n\
4137 link, utime will modify the symbolic link itself instead of the file the\n\
4138 link points to.\n\
4139It is an error to use dir_fd or follow_symlinks when specifying path\n\
4140 as an open file descriptor.\n\
4141dir_fd and follow_symlinks may not be available on your platform.\n\
4142 If they are unavailable, using them will raise a NotImplementedError.");
4143
4144typedef struct {
4145 int now;
4146 time_t atime_s;
4147 long atime_ns;
4148 time_t mtime_s;
4149 long mtime_ns;
4150} utime_t;
4151
4152/*
4153 * these macros assume that "utime" is a pointer to a utime_t
4154 * they also intentionally leak the declaration of a pointer named "time"
4155 */
4156#define UTIME_TO_TIMESPEC \
4157 struct timespec ts[2]; \
4158 struct timespec *time; \
4159 if (utime->now) \
4160 time = NULL; \
4161 else { \
4162 ts[0].tv_sec = utime->atime_s; \
4163 ts[0].tv_nsec = utime->atime_ns; \
4164 ts[1].tv_sec = utime->mtime_s; \
4165 ts[1].tv_nsec = utime->mtime_ns; \
4166 time = ts; \
4167 } \
4168
4169#define UTIME_TO_TIMEVAL \
4170 struct timeval tv[2]; \
4171 struct timeval *time; \
4172 if (utime->now) \
4173 time = NULL; \
4174 else { \
4175 tv[0].tv_sec = utime->atime_s; \
4176 tv[0].tv_usec = utime->atime_ns / 1000; \
4177 tv[1].tv_sec = utime->mtime_s; \
4178 tv[1].tv_usec = utime->mtime_ns / 1000; \
4179 time = tv; \
4180 } \
4181
4182#define UTIME_TO_UTIMBUF \
4183 struct utimbuf u[2]; \
4184 struct utimbuf *time; \
4185 if (utime->now) \
4186 time = NULL; \
4187 else { \
4188 u.actime = utime->atime_s; \
4189 u.modtime = utime->mtime_s; \
4190 time = u; \
4191 }
4192
4193#define UTIME_TO_TIME_T \
4194 time_t timet[2]; \
4195 struct timet time; \
4196 if (utime->now) \
4197 time = NULL; \
4198 else { \
4199 timet[0] = utime->atime_s; \
4200 timet[1] = utime->mtime_s; \
4201 time = &timet; \
4202 } \
4203
4204
4205#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4206
4207#if UTIME_HAVE_DIR_FD
4208
4209static int
4210utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4211{
4212#ifdef HAVE_UTIMENSAT
4213 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4214 UTIME_TO_TIMESPEC;
4215 return utimensat(dir_fd, path, time, flags);
4216#elif defined(HAVE_FUTIMESAT)
4217 UTIME_TO_TIMEVAL;
4218 /*
4219 * follow_symlinks will never be false here;
4220 * we only allow !follow_symlinks and dir_fd together
4221 * if we have utimensat()
4222 */
4223 assert(follow_symlinks);
4224 return futimesat(dir_fd, path, time);
4225#endif
4226}
4227
4228#endif
4229
4230#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4231
4232#if UTIME_HAVE_FD
4233
4234static int
4235utime_fd(utime_t *utime, int fd)
4236{
4237#ifdef HAVE_FUTIMENS
4238 UTIME_TO_TIMESPEC;
4239 return futimens(fd, time);
4240#else
4241 UTIME_TO_TIMEVAL;
4242 return futimes(fd, time);
4243#endif
4244}
4245
4246#endif
4247
4248
4249#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4250 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4251
4252#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4253
4254static int
4255utime_nofollow_symlinks(utime_t *utime, char *path)
4256{
4257#ifdef HAVE_UTIMENSAT
4258 UTIME_TO_TIMESPEC;
4259 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4260#else
4261 UTIME_TO_TIMEVAL;
4262 return lutimes(path, time);
4263#endif
4264}
4265
4266#endif
4267
4268#ifndef MS_WINDOWS
4269
4270static int
4271utime_default(utime_t *utime, char *path)
4272{
4273#ifdef HAVE_UTIMENSAT
4274 UTIME_TO_TIMESPEC;
4275 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4276#elif defined(HAVE_UTIMES)
4277 UTIME_TO_TIMEVAL;
4278 return utimes(path, time);
4279#elif defined(HAVE_UTIME_H)
4280 UTIME_TO_UTIMBUF;
4281 return utime(path, time);
4282#else
4283 UTIME_TO_TIME_T;
4284 return utime(path, time);
4285#endif
4286}
4287
4288#endif
4289
Larry Hastings76ad59b2012-05-03 00:30:07 -07004290static int
4291split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4292{
4293 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004294 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004295 divmod = PyNumber_Divmod(py_long, billion);
4296 if (!divmod)
4297 goto exit;
4298 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4299 if ((*s == -1) && PyErr_Occurred())
4300 goto exit;
4301 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004302 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004303 goto exit;
4304
4305 result = 1;
4306exit:
4307 Py_XDECREF(divmod);
4308 return result;
4309}
4310
Larry Hastings9cf065c2012-06-22 16:30:09 -07004311static PyObject *
4312posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004313{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004314 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004315 PyObject *times = NULL;
4316 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004317 int dir_fd = DEFAULT_DIR_FD;
4318 int follow_symlinks = 1;
4319 char *keywords[] = {"path", "times", "ns", "dir_fd",
4320 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004321
Larry Hastings9cf065c2012-06-22 16:30:09 -07004322 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004323
Larry Hastings9cf065c2012-06-22 16:30:09 -07004324#ifdef MS_WINDOWS
4325 HANDLE hFile;
4326 FILETIME atime, mtime;
4327#else
4328 int result;
4329#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004330
Larry Hastings9cf065c2012-06-22 16:30:09 -07004331 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004332
Larry Hastings9cf065c2012-06-22 16:30:09 -07004333 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004334 path.function_name = "utime";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004335#if UTIME_HAVE_FD
4336 path.allow_fd = 1;
4337#endif
4338 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4339 "O&|O$OO&p:utime", keywords,
4340 path_converter, &path,
4341 &times, &ns,
4342#if UTIME_HAVE_DIR_FD
4343 dir_fd_converter, &dir_fd,
4344#else
4345 dir_fd_unavailable, &dir_fd,
4346#endif
4347 &follow_symlinks
4348 ))
4349 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004350
Larry Hastings9cf065c2012-06-22 16:30:09 -07004351 if (times && (times != Py_None) && ns) {
4352 PyErr_SetString(PyExc_ValueError,
4353 "utime: you may specify either 'times'"
4354 " or 'ns' but not both");
4355 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004356 }
4357
4358 if (times && (times != Py_None)) {
4359 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004360 PyErr_SetString(PyExc_TypeError,
4361 "utime: 'times' must be either"
4362 " a tuple of two ints or None");
4363 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004364 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004365 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004366 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004367 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004368 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004369 &utime.mtime_s, &utime.mtime_ns) == -1) {
4370 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004371 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004372 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004373 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004374 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004375 PyErr_SetString(PyExc_TypeError,
4376 "utime: 'ns' must be a tuple of two ints");
4377 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004378 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004379 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004380 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004381 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004382 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004383 &utime.mtime_s, &utime.mtime_ns)) {
4384 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004385 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386 }
4387 else {
4388 /* times and ns are both None/unspecified. use "now". */
4389 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004390 }
4391
Larry Hastings9cf065c2012-06-22 16:30:09 -07004392#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4393 if (follow_symlinks_specified("utime", follow_symlinks))
4394 goto exit;
4395#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004396
Larry Hastings9cf065c2012-06-22 16:30:09 -07004397 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4398 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4399 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4400 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004401
Larry Hastings9cf065c2012-06-22 16:30:09 -07004402#if !defined(HAVE_UTIMENSAT)
4403 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004404 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004405 "utime: cannot use dir_fd and follow_symlinks "
4406 "together on this platform");
4407 goto exit;
4408 }
4409#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004410
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004411#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004412 Py_BEGIN_ALLOW_THREADS
4413 if (path.wide)
4414 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004415 NULL, OPEN_EXISTING,
4416 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004417 else
4418 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004419 NULL, OPEN_EXISTING,
4420 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004421 Py_END_ALLOW_THREADS
4422 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004423 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004424 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004425 }
4426
Larry Hastings9cf065c2012-06-22 16:30:09 -07004427 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004428 SYSTEMTIME now;
4429 GetSystemTime(&now);
4430 if (!SystemTimeToFileTime(&now, &mtime) ||
4431 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004432 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004433 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004434 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004435 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004437 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4438 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004439 }
4440 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4441 /* Avoid putting the file name into the error here,
4442 as that may confuse the user into believing that
4443 something is wrong with the file, when it also
4444 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004445 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004446 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004447 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004448#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004449 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004450
Larry Hastings9cf065c2012-06-22 16:30:09 -07004451#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4452 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4453 result = utime_nofollow_symlinks(&utime, path.narrow);
4454 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004455#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004456
4457#if UTIME_HAVE_DIR_FD
4458 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4459 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4460 else
4461#endif
4462
4463#if UTIME_HAVE_FD
4464 if (path.fd != -1)
4465 result = utime_fd(&utime, path.fd);
4466 else
4467#endif
4468
4469 result = utime_default(&utime, path.narrow);
4470
4471 Py_END_ALLOW_THREADS
4472
4473 if (result < 0) {
4474 /* see previous comment about not putting filename in error here */
4475 return_value = posix_error();
4476 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004477 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004478
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004479#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004480
4481 Py_INCREF(Py_None);
4482 return_value = Py_None;
4483
4484exit:
4485 path_cleanup(&path);
4486#ifdef MS_WINDOWS
4487 if (hFile != INVALID_HANDLE_VALUE)
4488 CloseHandle(hFile);
4489#endif
4490 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004491}
4492
Guido van Rossum3b066191991-06-04 19:40:25 +00004493/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004494
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004495PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004496"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004497Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004498
Barry Warsaw53699e91996-12-10 23:23:01 +00004499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004500posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004501{
Victor Stinner8c62be82010-05-06 00:08:46 +00004502 int sts;
4503 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4504 return NULL;
4505 _exit(sts);
4506 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004507}
4508
Martin v. Löwis114619e2002-10-07 06:44:21 +00004509#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4510static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004511free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004512{
Victor Stinner8c62be82010-05-06 00:08:46 +00004513 Py_ssize_t i;
4514 for (i = 0; i < count; i++)
4515 PyMem_Free(array[i]);
4516 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004517}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004518
Antoine Pitrou69f71142009-05-24 21:25:49 +00004519static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004520int fsconvert_strdup(PyObject *o, char**out)
4521{
Victor Stinner8c62be82010-05-06 00:08:46 +00004522 PyObject *bytes;
4523 Py_ssize_t size;
4524 if (!PyUnicode_FSConverter(o, &bytes))
4525 return 0;
4526 size = PyBytes_GET_SIZE(bytes);
4527 *out = PyMem_Malloc(size+1);
4528 if (!*out)
4529 return 0;
4530 memcpy(*out, PyBytes_AsString(bytes), size+1);
4531 Py_DECREF(bytes);
4532 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004533}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004534#endif
4535
Ross Lagerwall7807c352011-03-17 20:20:30 +02004536#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004537static char**
4538parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4539{
Victor Stinner8c62be82010-05-06 00:08:46 +00004540 char **envlist;
4541 Py_ssize_t i, pos, envc;
4542 PyObject *keys=NULL, *vals=NULL;
4543 PyObject *key, *val, *key2, *val2;
4544 char *p, *k, *v;
4545 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004546
Victor Stinner8c62be82010-05-06 00:08:46 +00004547 i = PyMapping_Size(env);
4548 if (i < 0)
4549 return NULL;
4550 envlist = PyMem_NEW(char *, i + 1);
4551 if (envlist == NULL) {
4552 PyErr_NoMemory();
4553 return NULL;
4554 }
4555 envc = 0;
4556 keys = PyMapping_Keys(env);
4557 vals = PyMapping_Values(env);
4558 if (!keys || !vals)
4559 goto error;
4560 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4561 PyErr_Format(PyExc_TypeError,
4562 "env.keys() or env.values() is not a list");
4563 goto error;
4564 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004565
Victor Stinner8c62be82010-05-06 00:08:46 +00004566 for (pos = 0; pos < i; pos++) {
4567 key = PyList_GetItem(keys, pos);
4568 val = PyList_GetItem(vals, pos);
4569 if (!key || !val)
4570 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004571
Victor Stinner8c62be82010-05-06 00:08:46 +00004572 if (PyUnicode_FSConverter(key, &key2) == 0)
4573 goto error;
4574 if (PyUnicode_FSConverter(val, &val2) == 0) {
4575 Py_DECREF(key2);
4576 goto error;
4577 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004578
Victor Stinner8c62be82010-05-06 00:08:46 +00004579 k = PyBytes_AsString(key2);
4580 v = PyBytes_AsString(val2);
4581 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004582
Victor Stinner8c62be82010-05-06 00:08:46 +00004583 p = PyMem_NEW(char, len);
4584 if (p == NULL) {
4585 PyErr_NoMemory();
4586 Py_DECREF(key2);
4587 Py_DECREF(val2);
4588 goto error;
4589 }
4590 PyOS_snprintf(p, len, "%s=%s", k, v);
4591 envlist[envc++] = p;
4592 Py_DECREF(key2);
4593 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004594 }
4595 Py_DECREF(vals);
4596 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004597
Victor Stinner8c62be82010-05-06 00:08:46 +00004598 envlist[envc] = 0;
4599 *envc_ptr = envc;
4600 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004601
4602error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004603 Py_XDECREF(keys);
4604 Py_XDECREF(vals);
4605 while (--envc >= 0)
4606 PyMem_DEL(envlist[envc]);
4607 PyMem_DEL(envlist);
4608 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004609}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004610
Ross Lagerwall7807c352011-03-17 20:20:30 +02004611static char**
4612parse_arglist(PyObject* argv, Py_ssize_t *argc)
4613{
4614 int i;
4615 char **argvlist = PyMem_NEW(char *, *argc+1);
4616 if (argvlist == NULL) {
4617 PyErr_NoMemory();
4618 return NULL;
4619 }
4620 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004621 PyObject* item = PySequence_ITEM(argv, i);
4622 if (item == NULL)
4623 goto fail;
4624 if (!fsconvert_strdup(item, &argvlist[i])) {
4625 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004626 goto fail;
4627 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004628 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004629 }
4630 argvlist[*argc] = NULL;
4631 return argvlist;
4632fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004633 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004634 free_string_array(argvlist, *argc);
4635 return NULL;
4636}
4637#endif
4638
4639#ifdef HAVE_EXECV
4640PyDoc_STRVAR(posix_execv__doc__,
4641"execv(path, args)\n\n\
4642Execute an executable path with arguments, replacing current process.\n\
4643\n\
4644 path: path of executable file\n\
4645 args: tuple or list of strings");
4646
4647static PyObject *
4648posix_execv(PyObject *self, PyObject *args)
4649{
4650 PyObject *opath;
4651 char *path;
4652 PyObject *argv;
4653 char **argvlist;
4654 Py_ssize_t argc;
4655
4656 /* execv has two arguments: (path, argv), where
4657 argv is a list or tuple of strings. */
4658
4659 if (!PyArg_ParseTuple(args, "O&O:execv",
4660 PyUnicode_FSConverter,
4661 &opath, &argv))
4662 return NULL;
4663 path = PyBytes_AsString(opath);
4664 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4665 PyErr_SetString(PyExc_TypeError,
4666 "execv() arg 2 must be a tuple or list");
4667 Py_DECREF(opath);
4668 return NULL;
4669 }
4670 argc = PySequence_Size(argv);
4671 if (argc < 1) {
4672 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4673 Py_DECREF(opath);
4674 return NULL;
4675 }
4676
4677 argvlist = parse_arglist(argv, &argc);
4678 if (argvlist == NULL) {
4679 Py_DECREF(opath);
4680 return NULL;
4681 }
4682
4683 execv(path, argvlist);
4684
4685 /* If we get here it's definitely an error */
4686
4687 free_string_array(argvlist, argc);
4688 Py_DECREF(opath);
4689 return posix_error();
4690}
4691
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004692PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004693"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004694Execute a path with arguments and environment, replacing current process.\n\
4695\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004696 path: path of executable file\n\
4697 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004698 env: dictionary of strings mapping to strings\n\
4699\n\
4700On some platforms, you may specify an open file descriptor for path;\n\
4701 execve will execute the program the file descriptor is open to.\n\
4702 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004703
Barry Warsaw53699e91996-12-10 23:23:01 +00004704static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004705posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004706{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004707 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004708 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004709 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004710 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004711 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004712 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004713
Victor Stinner8c62be82010-05-06 00:08:46 +00004714 /* execve has three arguments: (path, argv, env), where
4715 argv is a list or tuple of strings and env is a dictionary
4716 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004717
Larry Hastings9cf065c2012-06-22 16:30:09 -07004718 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004719 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720#ifdef HAVE_FEXECVE
4721 path.allow_fd = 1;
4722#endif
4723 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4724 path_converter, &path,
4725 &argv, &env
4726 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004727 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004728
Ross Lagerwall7807c352011-03-17 20:20:30 +02004729 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004730 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731 "execve: argv must be a tuple or list");
4732 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004733 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004734 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004735 if (!PyMapping_Check(env)) {
4736 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737 "execve: environment must be a mapping object");
4738 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004739 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004740
Ross Lagerwall7807c352011-03-17 20:20:30 +02004741 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004742 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004744 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004745
Victor Stinner8c62be82010-05-06 00:08:46 +00004746 envlist = parse_envlist(env, &envc);
4747 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004748 goto fail;
4749
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750#ifdef HAVE_FEXECVE
4751 if (path.fd > -1)
4752 fexecve(path.fd, argvlist, envlist);
4753 else
4754#endif
4755 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004756
4757 /* If we get here it's definitely an error */
4758
Victor Stinner292c8352012-10-30 02:17:38 +01004759 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004760
4761 while (--envc >= 0)
4762 PyMem_DEL(envlist[envc]);
4763 PyMem_DEL(envlist);
4764 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 if (argvlist)
4766 free_string_array(argvlist, argc);
4767 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004768 return NULL;
4769}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770#endif /* HAVE_EXECV */
4771
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004772
Guido van Rossuma1065681999-01-25 23:20:23 +00004773#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004774PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004775"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004776Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004777\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004778 mode: mode of process creation\n\
4779 path: path of executable file\n\
4780 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004781
4782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004783posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004784{
Victor Stinner8c62be82010-05-06 00:08:46 +00004785 PyObject *opath;
4786 char *path;
4787 PyObject *argv;
4788 char **argvlist;
4789 int mode, i;
4790 Py_ssize_t argc;
4791 Py_intptr_t spawnval;
4792 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004793
Victor Stinner8c62be82010-05-06 00:08:46 +00004794 /* spawnv has three arguments: (mode, path, argv), where
4795 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004796
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4798 PyUnicode_FSConverter,
4799 &opath, &argv))
4800 return NULL;
4801 path = PyBytes_AsString(opath);
4802 if (PyList_Check(argv)) {
4803 argc = PyList_Size(argv);
4804 getitem = PyList_GetItem;
4805 }
4806 else if (PyTuple_Check(argv)) {
4807 argc = PyTuple_Size(argv);
4808 getitem = PyTuple_GetItem;
4809 }
4810 else {
4811 PyErr_SetString(PyExc_TypeError,
4812 "spawnv() arg 2 must be a tuple or list");
4813 Py_DECREF(opath);
4814 return NULL;
4815 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004816
Victor Stinner8c62be82010-05-06 00:08:46 +00004817 argvlist = PyMem_NEW(char *, argc+1);
4818 if (argvlist == NULL) {
4819 Py_DECREF(opath);
4820 return PyErr_NoMemory();
4821 }
4822 for (i = 0; i < argc; i++) {
4823 if (!fsconvert_strdup((*getitem)(argv, i),
4824 &argvlist[i])) {
4825 free_string_array(argvlist, i);
4826 PyErr_SetString(
4827 PyExc_TypeError,
4828 "spawnv() arg 2 must contain only strings");
4829 Py_DECREF(opath);
4830 return NULL;
4831 }
4832 }
4833 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004834
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 if (mode == _OLD_P_OVERLAY)
4836 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004837
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 Py_BEGIN_ALLOW_THREADS
4839 spawnval = _spawnv(mode, path, argvlist);
4840 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00004841
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 free_string_array(argvlist, argc);
4843 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004844
Victor Stinner8c62be82010-05-06 00:08:46 +00004845 if (spawnval == -1)
4846 return posix_error();
4847 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004848#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004849 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004850#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004852#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004853}
4854
4855
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004856PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004857"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004858Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004859\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004860 mode: mode of process creation\n\
4861 path: path of executable file\n\
4862 args: tuple or list of arguments\n\
4863 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004864
4865static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004866posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004867{
Victor Stinner8c62be82010-05-06 00:08:46 +00004868 PyObject *opath;
4869 char *path;
4870 PyObject *argv, *env;
4871 char **argvlist;
4872 char **envlist;
4873 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004874 int mode;
4875 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004876 Py_intptr_t spawnval;
4877 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4878 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004879
Victor Stinner8c62be82010-05-06 00:08:46 +00004880 /* spawnve has four arguments: (mode, path, argv, env), where
4881 argv is a list or tuple of strings and env is a dictionary
4882 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004883
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4885 PyUnicode_FSConverter,
4886 &opath, &argv, &env))
4887 return NULL;
4888 path = PyBytes_AsString(opath);
4889 if (PyList_Check(argv)) {
4890 argc = PyList_Size(argv);
4891 getitem = PyList_GetItem;
4892 }
4893 else if (PyTuple_Check(argv)) {
4894 argc = PyTuple_Size(argv);
4895 getitem = PyTuple_GetItem;
4896 }
4897 else {
4898 PyErr_SetString(PyExc_TypeError,
4899 "spawnve() arg 2 must be a tuple or list");
4900 goto fail_0;
4901 }
4902 if (!PyMapping_Check(env)) {
4903 PyErr_SetString(PyExc_TypeError,
4904 "spawnve() arg 3 must be a mapping object");
4905 goto fail_0;
4906 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004907
Victor Stinner8c62be82010-05-06 00:08:46 +00004908 argvlist = PyMem_NEW(char *, argc+1);
4909 if (argvlist == NULL) {
4910 PyErr_NoMemory();
4911 goto fail_0;
4912 }
4913 for (i = 0; i < argc; i++) {
4914 if (!fsconvert_strdup((*getitem)(argv, i),
4915 &argvlist[i]))
4916 {
4917 lastarg = i;
4918 goto fail_1;
4919 }
4920 }
4921 lastarg = argc;
4922 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004923
Victor Stinner8c62be82010-05-06 00:08:46 +00004924 envlist = parse_envlist(env, &envc);
4925 if (envlist == NULL)
4926 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004927
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 if (mode == _OLD_P_OVERLAY)
4929 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004930
Victor Stinner8c62be82010-05-06 00:08:46 +00004931 Py_BEGIN_ALLOW_THREADS
4932 spawnval = _spawnve(mode, path, argvlist, envlist);
4933 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00004934
Victor Stinner8c62be82010-05-06 00:08:46 +00004935 if (spawnval == -1)
4936 (void) posix_error();
4937 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004938#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004939 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004940#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004941 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004942#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004943
Victor Stinner8c62be82010-05-06 00:08:46 +00004944 while (--envc >= 0)
4945 PyMem_DEL(envlist[envc]);
4946 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004947 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004949 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004950 Py_DECREF(opath);
4951 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004952}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004953
Guido van Rossuma1065681999-01-25 23:20:23 +00004954#endif /* HAVE_SPAWNV */
4955
4956
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004957#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004958PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004959"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004960Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4961\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004962Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004963
4964static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004965posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004966{
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 pid_t pid;
4968 int result = 0;
4969 _PyImport_AcquireLock();
4970 pid = fork1();
4971 if (pid == 0) {
4972 /* child: this clobbers and resets the import lock. */
4973 PyOS_AfterFork();
4974 } else {
4975 /* parent: release the import lock. */
4976 result = _PyImport_ReleaseLock();
4977 }
4978 if (pid == -1)
4979 return posix_error();
4980 if (result < 0) {
4981 /* Don't clobber the OSError if the fork failed. */
4982 PyErr_SetString(PyExc_RuntimeError,
4983 "not holding the import lock");
4984 return NULL;
4985 }
4986 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004987}
4988#endif
4989
4990
Guido van Rossumad0ee831995-03-01 10:34:45 +00004991#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004992PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004993"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004994Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004995Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004996
Barry Warsaw53699e91996-12-10 23:23:01 +00004997static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004998posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004999{
Victor Stinner8c62be82010-05-06 00:08:46 +00005000 pid_t pid;
5001 int result = 0;
5002 _PyImport_AcquireLock();
5003 pid = fork();
5004 if (pid == 0) {
5005 /* child: this clobbers and resets the import lock. */
5006 PyOS_AfterFork();
5007 } else {
5008 /* parent: release the import lock. */
5009 result = _PyImport_ReleaseLock();
5010 }
5011 if (pid == -1)
5012 return posix_error();
5013 if (result < 0) {
5014 /* Don't clobber the OSError if the fork failed. */
5015 PyErr_SetString(PyExc_RuntimeError,
5016 "not holding the import lock");
5017 return NULL;
5018 }
5019 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005020}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005021#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005022
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005023#ifdef HAVE_SCHED_H
5024
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005025#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5026
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005027PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5028"sched_get_priority_max(policy)\n\n\
5029Get the maximum scheduling priority for *policy*.");
5030
5031static PyObject *
5032posix_sched_get_priority_max(PyObject *self, PyObject *args)
5033{
5034 int policy, max;
5035
5036 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5037 return NULL;
5038 max = sched_get_priority_max(policy);
5039 if (max < 0)
5040 return posix_error();
5041 return PyLong_FromLong(max);
5042}
5043
5044PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5045"sched_get_priority_min(policy)\n\n\
5046Get the minimum scheduling priority for *policy*.");
5047
5048static PyObject *
5049posix_sched_get_priority_min(PyObject *self, PyObject *args)
5050{
5051 int policy, min;
5052
5053 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5054 return NULL;
5055 min = sched_get_priority_min(policy);
5056 if (min < 0)
5057 return posix_error();
5058 return PyLong_FromLong(min);
5059}
5060
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005061#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5062
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005063#ifdef HAVE_SCHED_SETSCHEDULER
5064
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005065PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5066"sched_getscheduler(pid)\n\n\
5067Get the scheduling policy for the process with a PID of *pid*.\n\
5068Passing a PID of 0 returns the scheduling policy for the calling process.");
5069
5070static PyObject *
5071posix_sched_getscheduler(PyObject *self, PyObject *args)
5072{
5073 pid_t pid;
5074 int policy;
5075
5076 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5077 return NULL;
5078 policy = sched_getscheduler(pid);
5079 if (policy < 0)
5080 return posix_error();
5081 return PyLong_FromLong(policy);
5082}
5083
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005084#endif
5085
5086#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5087
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005088static PyObject *
5089sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5090{
5091 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005092 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005093
5094 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5095 return NULL;
5096 res = PyStructSequence_New(type);
5097 if (!res)
5098 return NULL;
5099 Py_INCREF(priority);
5100 PyStructSequence_SET_ITEM(res, 0, priority);
5101 return res;
5102}
5103
5104PyDoc_STRVAR(sched_param__doc__,
5105"sched_param(sched_priority): A scheduling parameter.\n\n\
5106Current has only one field: sched_priority");
5107
5108static PyStructSequence_Field sched_param_fields[] = {
5109 {"sched_priority", "the scheduling priority"},
5110 {0}
5111};
5112
5113static PyStructSequence_Desc sched_param_desc = {
5114 "sched_param", /* name */
5115 sched_param__doc__, /* doc */
5116 sched_param_fields,
5117 1
5118};
5119
5120static int
5121convert_sched_param(PyObject *param, struct sched_param *res)
5122{
5123 long priority;
5124
5125 if (Py_TYPE(param) != &SchedParamType) {
5126 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5127 return 0;
5128 }
5129 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5130 if (priority == -1 && PyErr_Occurred())
5131 return 0;
5132 if (priority > INT_MAX || priority < INT_MIN) {
5133 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5134 return 0;
5135 }
5136 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5137 return 1;
5138}
5139
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005140#endif
5141
5142#ifdef HAVE_SCHED_SETSCHEDULER
5143
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005144PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5145"sched_setscheduler(pid, policy, param)\n\n\
5146Set the scheduling policy, *policy*, for *pid*.\n\
5147If *pid* is 0, the calling process is changed.\n\
5148*param* is an instance of sched_param.");
5149
5150static PyObject *
5151posix_sched_setscheduler(PyObject *self, PyObject *args)
5152{
5153 pid_t pid;
5154 int policy;
5155 struct sched_param param;
5156
5157 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5158 &pid, &policy, &convert_sched_param, &param))
5159 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005160
5161 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005162 ** sched_setscheduler() returns 0 in Linux, but the previous
5163 ** scheduling policy under Solaris/Illumos, and others.
5164 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005165 */
5166 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005167 return posix_error();
5168 Py_RETURN_NONE;
5169}
5170
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005171#endif
5172
5173#ifdef HAVE_SCHED_SETPARAM
5174
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005175PyDoc_STRVAR(posix_sched_getparam__doc__,
5176"sched_getparam(pid) -> sched_param\n\n\
5177Returns scheduling parameters for the process with *pid* as an instance of the\n\
5178sched_param class. A PID of 0 means the calling process.");
5179
5180static PyObject *
5181posix_sched_getparam(PyObject *self, PyObject *args)
5182{
5183 pid_t pid;
5184 struct sched_param param;
5185 PyObject *res, *priority;
5186
5187 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5188 return NULL;
5189 if (sched_getparam(pid, &param))
5190 return posix_error();
5191 res = PyStructSequence_New(&SchedParamType);
5192 if (!res)
5193 return NULL;
5194 priority = PyLong_FromLong(param.sched_priority);
5195 if (!priority) {
5196 Py_DECREF(res);
5197 return NULL;
5198 }
5199 PyStructSequence_SET_ITEM(res, 0, priority);
5200 return res;
5201}
5202
5203PyDoc_STRVAR(posix_sched_setparam__doc__,
5204"sched_setparam(pid, param)\n\n\
5205Set scheduling parameters for a process with PID *pid*.\n\
5206A PID of 0 means the calling process.");
5207
5208static PyObject *
5209posix_sched_setparam(PyObject *self, PyObject *args)
5210{
5211 pid_t pid;
5212 struct sched_param param;
5213
5214 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5215 &pid, &convert_sched_param, &param))
5216 return NULL;
5217 if (sched_setparam(pid, &param))
5218 return posix_error();
5219 Py_RETURN_NONE;
5220}
5221
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005222#endif
5223
5224#ifdef HAVE_SCHED_RR_GET_INTERVAL
5225
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005226PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5227"sched_rr_get_interval(pid) -> float\n\n\
5228Return the round-robin quantum for the process with PID *pid* in seconds.");
5229
5230static PyObject *
5231posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5232{
5233 pid_t pid;
5234 struct timespec interval;
5235
5236 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5237 return NULL;
5238 if (sched_rr_get_interval(pid, &interval))
5239 return posix_error();
5240 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5241}
5242
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005243#endif
5244
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005245PyDoc_STRVAR(posix_sched_yield__doc__,
5246"sched_yield()\n\n\
5247Voluntarily relinquish the CPU.");
5248
5249static PyObject *
5250posix_sched_yield(PyObject *self, PyObject *noargs)
5251{
5252 if (sched_yield())
5253 return posix_error();
5254 Py_RETURN_NONE;
5255}
5256
Benjamin Peterson2740af82011-08-02 17:41:34 -05005257#ifdef HAVE_SCHED_SETAFFINITY
5258
Antoine Pitrou84869872012-08-04 16:16:35 +02005259/* The minimum number of CPUs allocated in a cpu_set_t */
5260static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005261
5262PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5263"sched_setaffinity(pid, cpu_set)\n\n\
5264Set the affinity of the process with PID *pid* to *cpu_set*.");
5265
5266static PyObject *
5267posix_sched_setaffinity(PyObject *self, PyObject *args)
5268{
5269 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005270 int ncpus;
5271 size_t setsize;
5272 cpu_set_t *mask = NULL;
5273 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005274
Antoine Pitrou84869872012-08-04 16:16:35 +02005275 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5276 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005277 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005278
5279 iterator = PyObject_GetIter(iterable);
5280 if (iterator == NULL)
5281 return NULL;
5282
5283 ncpus = NCPUS_START;
5284 setsize = CPU_ALLOC_SIZE(ncpus);
5285 mask = CPU_ALLOC(ncpus);
5286 if (mask == NULL) {
5287 PyErr_NoMemory();
5288 goto error;
5289 }
5290 CPU_ZERO_S(setsize, mask);
5291
5292 while ((item = PyIter_Next(iterator))) {
5293 long cpu;
5294 if (!PyLong_Check(item)) {
5295 PyErr_Format(PyExc_TypeError,
5296 "expected an iterator of ints, "
5297 "but iterator yielded %R",
5298 Py_TYPE(item));
5299 Py_DECREF(item);
5300 goto error;
5301 }
5302 cpu = PyLong_AsLong(item);
5303 Py_DECREF(item);
5304 if (cpu < 0) {
5305 if (!PyErr_Occurred())
5306 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5307 goto error;
5308 }
5309 if (cpu > INT_MAX - 1) {
5310 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5311 goto error;
5312 }
5313 if (cpu >= ncpus) {
5314 /* Grow CPU mask to fit the CPU number */
5315 int newncpus = ncpus;
5316 cpu_set_t *newmask;
5317 size_t newsetsize;
5318 while (newncpus <= cpu) {
5319 if (newncpus > INT_MAX / 2)
5320 newncpus = cpu + 1;
5321 else
5322 newncpus = newncpus * 2;
5323 }
5324 newmask = CPU_ALLOC(newncpus);
5325 if (newmask == NULL) {
5326 PyErr_NoMemory();
5327 goto error;
5328 }
5329 newsetsize = CPU_ALLOC_SIZE(newncpus);
5330 CPU_ZERO_S(newsetsize, newmask);
5331 memcpy(newmask, mask, setsize);
5332 CPU_FREE(mask);
5333 setsize = newsetsize;
5334 mask = newmask;
5335 ncpus = newncpus;
5336 }
5337 CPU_SET_S(cpu, setsize, mask);
5338 }
5339 Py_CLEAR(iterator);
5340
5341 if (sched_setaffinity(pid, setsize, mask)) {
5342 posix_error();
5343 goto error;
5344 }
5345 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005346 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005347
5348error:
5349 if (mask)
5350 CPU_FREE(mask);
5351 Py_XDECREF(iterator);
5352 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005353}
5354
5355PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5356"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5357Return the affinity of the process with PID *pid*.\n\
5358The returned cpu_set will be of size *ncpus*.");
5359
5360static PyObject *
5361posix_sched_getaffinity(PyObject *self, PyObject *args)
5362{
5363 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005364 int cpu, ncpus, count;
5365 size_t setsize;
5366 cpu_set_t *mask = NULL;
5367 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005368
Antoine Pitrou84869872012-08-04 16:16:35 +02005369 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5370 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005371 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005372
5373 ncpus = NCPUS_START;
5374 while (1) {
5375 setsize = CPU_ALLOC_SIZE(ncpus);
5376 mask = CPU_ALLOC(ncpus);
5377 if (mask == NULL)
5378 return PyErr_NoMemory();
5379 if (sched_getaffinity(pid, setsize, mask) == 0)
5380 break;
5381 CPU_FREE(mask);
5382 if (errno != EINVAL)
5383 return posix_error();
5384 if (ncpus > INT_MAX / 2) {
5385 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5386 "a large enough CPU set");
5387 return NULL;
5388 }
5389 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005390 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005391
5392 res = PySet_New(NULL);
5393 if (res == NULL)
5394 goto error;
5395 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5396 if (CPU_ISSET_S(cpu, setsize, mask)) {
5397 PyObject *cpu_num = PyLong_FromLong(cpu);
5398 --count;
5399 if (cpu_num == NULL)
5400 goto error;
5401 if (PySet_Add(res, cpu_num)) {
5402 Py_DECREF(cpu_num);
5403 goto error;
5404 }
5405 Py_DECREF(cpu_num);
5406 }
5407 }
5408 CPU_FREE(mask);
5409 return res;
5410
5411error:
5412 if (mask)
5413 CPU_FREE(mask);
5414 Py_XDECREF(res);
5415 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005416}
5417
Benjamin Peterson2740af82011-08-02 17:41:34 -05005418#endif /* HAVE_SCHED_SETAFFINITY */
5419
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005420#endif /* HAVE_SCHED_H */
5421
Neal Norwitzb59798b2003-03-21 01:43:31 +00005422/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005423/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5424#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005425#define DEV_PTY_FILE "/dev/ptc"
5426#define HAVE_DEV_PTMX
5427#else
5428#define DEV_PTY_FILE "/dev/ptmx"
5429#endif
5430
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005431#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005432#ifdef HAVE_PTY_H
5433#include <pty.h>
5434#else
5435#ifdef HAVE_LIBUTIL_H
5436#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005437#else
5438#ifdef HAVE_UTIL_H
5439#include <util.h>
5440#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005441#endif /* HAVE_LIBUTIL_H */
5442#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005443#ifdef HAVE_STROPTS_H
5444#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005445#endif
5446#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005447
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005448#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005449PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005450"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005451Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005452
5453static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005454posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005455{
Victor Stinner8c62be82010-05-06 00:08:46 +00005456 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005457#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005458 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005459#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005460#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005461 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005462#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005463 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005464#endif
5465#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005466
Thomas Wouters70c21a12000-07-14 14:28:33 +00005467#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005468 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5469 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005470#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005471 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5472 if (slave_name == NULL)
5473 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005474
Victor Stinner8c62be82010-05-06 00:08:46 +00005475 slave_fd = open(slave_name, O_RDWR);
5476 if (slave_fd < 0)
5477 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005478#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005479 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5480 if (master_fd < 0)
5481 return posix_error();
5482 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5483 /* change permission of slave */
5484 if (grantpt(master_fd) < 0) {
5485 PyOS_setsig(SIGCHLD, sig_saved);
5486 return posix_error();
5487 }
5488 /* unlock slave */
5489 if (unlockpt(master_fd) < 0) {
5490 PyOS_setsig(SIGCHLD, sig_saved);
5491 return posix_error();
5492 }
5493 PyOS_setsig(SIGCHLD, sig_saved);
5494 slave_name = ptsname(master_fd); /* get name of slave */
5495 if (slave_name == NULL)
5496 return posix_error();
5497 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5498 if (slave_fd < 0)
5499 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005500#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005501 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5502 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005503#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005504 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005505#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005506#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005507#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005508
Victor Stinner8c62be82010-05-06 00:08:46 +00005509 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005510
Fred Drake8cef4cf2000-06-28 16:40:38 +00005511}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005512#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005513
5514#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005516"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005517Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5518Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005520
5521static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005522posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005523{
Victor Stinner8c62be82010-05-06 00:08:46 +00005524 int master_fd = -1, result = 0;
5525 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005526
Victor Stinner8c62be82010-05-06 00:08:46 +00005527 _PyImport_AcquireLock();
5528 pid = forkpty(&master_fd, NULL, NULL, NULL);
5529 if (pid == 0) {
5530 /* child: this clobbers and resets the import lock. */
5531 PyOS_AfterFork();
5532 } else {
5533 /* parent: release the import lock. */
5534 result = _PyImport_ReleaseLock();
5535 }
5536 if (pid == -1)
5537 return posix_error();
5538 if (result < 0) {
5539 /* Don't clobber the OSError if the fork failed. */
5540 PyErr_SetString(PyExc_RuntimeError,
5541 "not holding the import lock");
5542 return NULL;
5543 }
5544 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005545}
5546#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005547
Ross Lagerwall7807c352011-03-17 20:20:30 +02005548
Guido van Rossumad0ee831995-03-01 10:34:45 +00005549#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005550PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005551"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005552Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005553
Barry Warsaw53699e91996-12-10 23:23:01 +00005554static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005555posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005556{
Victor Stinner8c62be82010-05-06 00:08:46 +00005557 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005558}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005559#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005560
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005561
Guido van Rossumad0ee831995-03-01 10:34:45 +00005562#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005563PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005564"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005565Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005566
Barry Warsaw53699e91996-12-10 23:23:01 +00005567static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005568posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005569{
Victor Stinner8c62be82010-05-06 00:08:46 +00005570 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005571}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005572#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005573
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005574
Guido van Rossumad0ee831995-03-01 10:34:45 +00005575#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005576PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005577"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005578Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005579
Barry Warsaw53699e91996-12-10 23:23:01 +00005580static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005581posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005582{
Victor Stinner8c62be82010-05-06 00:08:46 +00005583 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005584}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005585#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005586
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005587
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005588PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005589"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005590Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005591
Barry Warsaw53699e91996-12-10 23:23:01 +00005592static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005593posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005594{
Victor Stinner8c62be82010-05-06 00:08:46 +00005595 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005596}
5597
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005598#ifdef HAVE_GETGROUPLIST
5599PyDoc_STRVAR(posix_getgrouplist__doc__,
5600"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5601Returns a list of groups to which a user belongs.\n\n\
5602 user: username to lookup\n\
5603 group: base group id of the user");
5604
5605static PyObject *
5606posix_getgrouplist(PyObject *self, PyObject *args)
5607{
5608#ifdef NGROUPS_MAX
5609#define MAX_GROUPS NGROUPS_MAX
5610#else
5611 /* defined to be 16 on Solaris7, so this should be a small number */
5612#define MAX_GROUPS 64
5613#endif
5614
5615 const char *user;
5616 int i, ngroups;
5617 PyObject *list;
5618#ifdef __APPLE__
5619 int *groups, basegid;
5620#else
5621 gid_t *groups, basegid;
5622#endif
5623 ngroups = MAX_GROUPS;
5624
5625 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5626 return NULL;
5627
5628#ifdef __APPLE__
5629 groups = PyMem_Malloc(ngroups * sizeof(int));
5630#else
5631 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5632#endif
5633 if (groups == NULL)
5634 return PyErr_NoMemory();
5635
5636 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5637 PyMem_Del(groups);
5638 return posix_error();
5639 }
5640
5641 list = PyList_New(ngroups);
5642 if (list == NULL) {
5643 PyMem_Del(groups);
5644 return NULL;
5645 }
5646
5647 for (i = 0; i < ngroups; i++) {
5648 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5649 if (o == NULL) {
5650 Py_DECREF(list);
5651 PyMem_Del(groups);
5652 return NULL;
5653 }
5654 PyList_SET_ITEM(list, i, o);
5655 }
5656
5657 PyMem_Del(groups);
5658
5659 return list;
5660}
5661#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005662
Fred Drakec9680921999-12-13 16:37:25 +00005663#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005664PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005665"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005666Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005667
5668static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005669posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005670{
5671 PyObject *result = NULL;
5672
Fred Drakec9680921999-12-13 16:37:25 +00005673#ifdef NGROUPS_MAX
5674#define MAX_GROUPS NGROUPS_MAX
5675#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005676 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005677#define MAX_GROUPS 64
5678#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005679 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005680
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005681 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005682 * This is a helper variable to store the intermediate result when
5683 * that happens.
5684 *
5685 * To keep the code readable the OSX behaviour is unconditional,
5686 * according to the POSIX spec this should be safe on all unix-y
5687 * systems.
5688 */
5689 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005690 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005691
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005693 if (n < 0) {
5694 if (errno == EINVAL) {
5695 n = getgroups(0, NULL);
5696 if (n == -1) {
5697 return posix_error();
5698 }
5699 if (n == 0) {
5700 /* Avoid malloc(0) */
5701 alt_grouplist = grouplist;
5702 } else {
5703 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5704 if (alt_grouplist == NULL) {
5705 errno = EINVAL;
5706 return posix_error();
5707 }
5708 n = getgroups(n, alt_grouplist);
5709 if (n == -1) {
5710 PyMem_Free(alt_grouplist);
5711 return posix_error();
5712 }
5713 }
5714 } else {
5715 return posix_error();
5716 }
5717 }
5718 result = PyList_New(n);
5719 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005720 int i;
5721 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005722 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005723 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005724 Py_DECREF(result);
5725 result = NULL;
5726 break;
Fred Drakec9680921999-12-13 16:37:25 +00005727 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005728 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005729 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005730 }
5731
5732 if (alt_grouplist != grouplist) {
5733 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005734 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005735
Fred Drakec9680921999-12-13 16:37:25 +00005736 return result;
5737}
5738#endif
5739
Antoine Pitroub7572f02009-12-02 20:46:48 +00005740#ifdef HAVE_INITGROUPS
5741PyDoc_STRVAR(posix_initgroups__doc__,
5742"initgroups(username, gid) -> None\n\n\
5743Call the system initgroups() to initialize the group access list with all of\n\
5744the groups of which the specified username is a member, plus the specified\n\
5745group id.");
5746
5747static PyObject *
5748posix_initgroups(PyObject *self, PyObject *args)
5749{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005750 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005751 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005752 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005753 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005754
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005755 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5756 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005757 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005758 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005759
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005760 res = initgroups(username, (gid_t) gid);
5761 Py_DECREF(oname);
5762 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005763 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005764
Victor Stinner8c62be82010-05-06 00:08:46 +00005765 Py_INCREF(Py_None);
5766 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005767}
5768#endif
5769
Martin v. Löwis606edc12002-06-13 21:09:11 +00005770#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005771PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005772"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005773Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005774
5775static PyObject *
5776posix_getpgid(PyObject *self, PyObject *args)
5777{
Victor Stinner8c62be82010-05-06 00:08:46 +00005778 pid_t pid, pgid;
5779 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5780 return NULL;
5781 pgid = getpgid(pid);
5782 if (pgid < 0)
5783 return posix_error();
5784 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005785}
5786#endif /* HAVE_GETPGID */
5787
5788
Guido van Rossumb6775db1994-08-01 11:34:53 +00005789#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005790PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005791"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005792Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005793
Barry Warsaw53699e91996-12-10 23:23:01 +00005794static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005795posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005796{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005797#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005798 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005799#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005800 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005801#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005802}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005803#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005805
Guido van Rossumb6775db1994-08-01 11:34:53 +00005806#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005807PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005808"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005809Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005810
Barry Warsaw53699e91996-12-10 23:23:01 +00005811static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005812posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005813{
Guido van Rossum64933891994-10-20 21:56:42 +00005814#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005815 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005816#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005818#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005819 return posix_error();
5820 Py_INCREF(Py_None);
5821 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005822}
5823
Guido van Rossumb6775db1994-08-01 11:34:53 +00005824#endif /* HAVE_SETPGRP */
5825
Guido van Rossumad0ee831995-03-01 10:34:45 +00005826#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005827
5828#ifdef MS_WINDOWS
5829#include <tlhelp32.h>
5830
5831static PyObject*
5832win32_getppid()
5833{
5834 HANDLE snapshot;
5835 pid_t mypid;
5836 PyObject* result = NULL;
5837 BOOL have_record;
5838 PROCESSENTRY32 pe;
5839
5840 mypid = getpid(); /* This function never fails */
5841
5842 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5843 if (snapshot == INVALID_HANDLE_VALUE)
5844 return PyErr_SetFromWindowsErr(GetLastError());
5845
5846 pe.dwSize = sizeof(pe);
5847 have_record = Process32First(snapshot, &pe);
5848 while (have_record) {
5849 if (mypid == (pid_t)pe.th32ProcessID) {
5850 /* We could cache the ulong value in a static variable. */
5851 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5852 break;
5853 }
5854
5855 have_record = Process32Next(snapshot, &pe);
5856 }
5857
5858 /* If our loop exits and our pid was not found (result will be NULL)
5859 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5860 * error anyway, so let's raise it. */
5861 if (!result)
5862 result = PyErr_SetFromWindowsErr(GetLastError());
5863
5864 CloseHandle(snapshot);
5865
5866 return result;
5867}
5868#endif /*MS_WINDOWS*/
5869
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005870PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005871"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005872Return the parent's process id. If the parent process has already exited,\n\
5873Windows machines will still return its id; others systems will return the id\n\
5874of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005875
Barry Warsaw53699e91996-12-10 23:23:01 +00005876static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005877posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005878{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005879#ifdef MS_WINDOWS
5880 return win32_getppid();
5881#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005882 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005883#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005884}
5885#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005887
Fred Drake12c6e2d1999-12-14 21:25:03 +00005888#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005889PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005890"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005891Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005892
5893static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005894posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005895{
Victor Stinner8c62be82010-05-06 00:08:46 +00005896 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005897#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005898 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005899 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005900
5901 if (GetUserNameW(user_name, &num_chars)) {
5902 /* num_chars is the number of unicode chars plus null terminator */
5903 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005904 }
5905 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005906 result = PyErr_SetFromWindowsErr(GetLastError());
5907#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005908 char *name;
5909 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005910
Victor Stinner8c62be82010-05-06 00:08:46 +00005911 errno = 0;
5912 name = getlogin();
5913 if (name == NULL) {
5914 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005915 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005916 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005917 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 }
5919 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005920 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005921 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005922#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005923 return result;
5924}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005925#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005926
Guido van Rossumad0ee831995-03-01 10:34:45 +00005927#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005928PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005929"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005930Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005931
Barry Warsaw53699e91996-12-10 23:23:01 +00005932static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005933posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005934{
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005936}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005937#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005938
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005939
Guido van Rossumad0ee831995-03-01 10:34:45 +00005940#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005941PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005942"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005943Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005944
Barry Warsaw53699e91996-12-10 23:23:01 +00005945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005946posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005947{
Victor Stinner8c62be82010-05-06 00:08:46 +00005948 pid_t pid;
5949 int sig;
5950 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5951 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 if (kill(pid, sig) == -1)
5953 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 Py_INCREF(Py_None);
5955 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005956}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005957#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005958
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005959#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005960PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005961"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005962Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005963
5964static PyObject *
5965posix_killpg(PyObject *self, PyObject *args)
5966{
Victor Stinner8c62be82010-05-06 00:08:46 +00005967 int sig;
5968 pid_t pgid;
5969 /* XXX some man pages make the `pgid` parameter an int, others
5970 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5971 take the same type. Moreover, pid_t is always at least as wide as
5972 int (else compilation of this module fails), which is safe. */
5973 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5974 return NULL;
5975 if (killpg(pgid, sig) == -1)
5976 return posix_error();
5977 Py_INCREF(Py_None);
5978 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005979}
5980#endif
5981
Brian Curtineb24d742010-04-12 17:16:38 +00005982#ifdef MS_WINDOWS
5983PyDoc_STRVAR(win32_kill__doc__,
5984"kill(pid, sig)\n\n\
5985Kill a process with a signal.");
5986
5987static PyObject *
5988win32_kill(PyObject *self, PyObject *args)
5989{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005990 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005991 DWORD pid, sig, err;
5992 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005993
Victor Stinner8c62be82010-05-06 00:08:46 +00005994 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5995 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005996
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 /* Console processes which share a common console can be sent CTRL+C or
5998 CTRL+BREAK events, provided they handle said events. */
5999 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6000 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6001 err = GetLastError();
6002 PyErr_SetFromWindowsErr(err);
6003 }
6004 else
6005 Py_RETURN_NONE;
6006 }
Brian Curtineb24d742010-04-12 17:16:38 +00006007
Victor Stinner8c62be82010-05-06 00:08:46 +00006008 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6009 attempt to open and terminate the process. */
6010 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6011 if (handle == NULL) {
6012 err = GetLastError();
6013 return PyErr_SetFromWindowsErr(err);
6014 }
Brian Curtineb24d742010-04-12 17:16:38 +00006015
Victor Stinner8c62be82010-05-06 00:08:46 +00006016 if (TerminateProcess(handle, sig) == 0) {
6017 err = GetLastError();
6018 result = PyErr_SetFromWindowsErr(err);
6019 } else {
6020 Py_INCREF(Py_None);
6021 result = Py_None;
6022 }
Brian Curtineb24d742010-04-12 17:16:38 +00006023
Victor Stinner8c62be82010-05-06 00:08:46 +00006024 CloseHandle(handle);
6025 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006026}
6027#endif /* MS_WINDOWS */
6028
Guido van Rossumc0125471996-06-28 18:55:32 +00006029#ifdef HAVE_PLOCK
6030
6031#ifdef HAVE_SYS_LOCK_H
6032#include <sys/lock.h>
6033#endif
6034
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006035PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006036"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006037Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006038
Barry Warsaw53699e91996-12-10 23:23:01 +00006039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006040posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006041{
Victor Stinner8c62be82010-05-06 00:08:46 +00006042 int op;
6043 if (!PyArg_ParseTuple(args, "i:plock", &op))
6044 return NULL;
6045 if (plock(op) == -1)
6046 return posix_error();
6047 Py_INCREF(Py_None);
6048 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006049}
6050#endif
6051
Guido van Rossumb6775db1994-08-01 11:34:53 +00006052#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006053PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006054"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006055Set the current process's user id.");
6056
Barry Warsaw53699e91996-12-10 23:23:01 +00006057static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006058posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006059{
Victor Stinner8c62be82010-05-06 00:08:46 +00006060 long uid_arg;
6061 uid_t uid;
6062 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6063 return NULL;
6064 uid = uid_arg;
6065 if (uid != uid_arg) {
6066 PyErr_SetString(PyExc_OverflowError, "user id too big");
6067 return NULL;
6068 }
6069 if (setuid(uid) < 0)
6070 return posix_error();
6071 Py_INCREF(Py_None);
6072 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006073}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006074#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006076
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006077#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006078PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006079"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080Set the current process's effective user id.");
6081
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006082static PyObject *
6083posix_seteuid (PyObject *self, PyObject *args)
6084{
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 long euid_arg;
6086 uid_t euid;
6087 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6088 return NULL;
6089 euid = euid_arg;
6090 if (euid != euid_arg) {
6091 PyErr_SetString(PyExc_OverflowError, "user id too big");
6092 return NULL;
6093 }
6094 if (seteuid(euid) < 0) {
6095 return posix_error();
6096 } else {
6097 Py_INCREF(Py_None);
6098 return Py_None;
6099 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006100}
6101#endif /* HAVE_SETEUID */
6102
6103#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006104PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006105"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006106Set the current process's effective group id.");
6107
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006108static PyObject *
6109posix_setegid (PyObject *self, PyObject *args)
6110{
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 long egid_arg;
6112 gid_t egid;
6113 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6114 return NULL;
6115 egid = egid_arg;
6116 if (egid != egid_arg) {
6117 PyErr_SetString(PyExc_OverflowError, "group id too big");
6118 return NULL;
6119 }
6120 if (setegid(egid) < 0) {
6121 return posix_error();
6122 } else {
6123 Py_INCREF(Py_None);
6124 return Py_None;
6125 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006126}
6127#endif /* HAVE_SETEGID */
6128
6129#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006130PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006131"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006132Set the current process's real and effective user ids.");
6133
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006134static PyObject *
6135posix_setreuid (PyObject *self, PyObject *args)
6136{
Victor Stinner8c62be82010-05-06 00:08:46 +00006137 long ruid_arg, euid_arg;
6138 uid_t ruid, euid;
6139 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6140 return NULL;
6141 if (ruid_arg == -1)
6142 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6143 else
6144 ruid = ruid_arg; /* otherwise, assign from our long */
6145 if (euid_arg == -1)
6146 euid = (uid_t)-1;
6147 else
6148 euid = euid_arg;
6149 if ((euid_arg != -1 && euid != euid_arg) ||
6150 (ruid_arg != -1 && ruid != ruid_arg)) {
6151 PyErr_SetString(PyExc_OverflowError, "user id too big");
6152 return NULL;
6153 }
6154 if (setreuid(ruid, euid) < 0) {
6155 return posix_error();
6156 } else {
6157 Py_INCREF(Py_None);
6158 return Py_None;
6159 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006160}
6161#endif /* HAVE_SETREUID */
6162
6163#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006164PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006165"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006166Set the current process's real and effective group ids.");
6167
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006168static PyObject *
6169posix_setregid (PyObject *self, PyObject *args)
6170{
Victor Stinner8c62be82010-05-06 00:08:46 +00006171 long rgid_arg, egid_arg;
6172 gid_t rgid, egid;
6173 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6174 return NULL;
6175 if (rgid_arg == -1)
6176 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6177 else
6178 rgid = rgid_arg; /* otherwise, assign from our long */
6179 if (egid_arg == -1)
6180 egid = (gid_t)-1;
6181 else
6182 egid = egid_arg;
6183 if ((egid_arg != -1 && egid != egid_arg) ||
6184 (rgid_arg != -1 && rgid != rgid_arg)) {
6185 PyErr_SetString(PyExc_OverflowError, "group id too big");
6186 return NULL;
6187 }
6188 if (setregid(rgid, egid) < 0) {
6189 return posix_error();
6190 } else {
6191 Py_INCREF(Py_None);
6192 return Py_None;
6193 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006194}
6195#endif /* HAVE_SETREGID */
6196
Guido van Rossumb6775db1994-08-01 11:34:53 +00006197#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006198PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006199"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006200Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006201
Barry Warsaw53699e91996-12-10 23:23:01 +00006202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006203posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006204{
Victor Stinner8c62be82010-05-06 00:08:46 +00006205 long gid_arg;
6206 gid_t gid;
6207 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6208 return NULL;
6209 gid = gid_arg;
6210 if (gid != gid_arg) {
6211 PyErr_SetString(PyExc_OverflowError, "group id too big");
6212 return NULL;
6213 }
6214 if (setgid(gid) < 0)
6215 return posix_error();
6216 Py_INCREF(Py_None);
6217 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006218}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006219#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006220
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006221#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006222PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006223"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006224Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006225
6226static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006227posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006228{
Victor Stinner8c62be82010-05-06 00:08:46 +00006229 int i, len;
6230 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006231
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 if (!PySequence_Check(groups)) {
6233 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6234 return NULL;
6235 }
6236 len = PySequence_Size(groups);
6237 if (len > MAX_GROUPS) {
6238 PyErr_SetString(PyExc_ValueError, "too many groups");
6239 return NULL;
6240 }
6241 for(i = 0; i < len; i++) {
6242 PyObject *elem;
6243 elem = PySequence_GetItem(groups, i);
6244 if (!elem)
6245 return NULL;
6246 if (!PyLong_Check(elem)) {
6247 PyErr_SetString(PyExc_TypeError,
6248 "groups must be integers");
6249 Py_DECREF(elem);
6250 return NULL;
6251 } else {
6252 unsigned long x = PyLong_AsUnsignedLong(elem);
6253 if (PyErr_Occurred()) {
6254 PyErr_SetString(PyExc_TypeError,
6255 "group id too big");
6256 Py_DECREF(elem);
6257 return NULL;
6258 }
6259 grouplist[i] = x;
6260 /* read back the value to see if it fitted in gid_t */
6261 if (grouplist[i] != x) {
6262 PyErr_SetString(PyExc_TypeError,
6263 "group id too big");
6264 Py_DECREF(elem);
6265 return NULL;
6266 }
6267 }
6268 Py_DECREF(elem);
6269 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006270
Victor Stinner8c62be82010-05-06 00:08:46 +00006271 if (setgroups(len, grouplist) < 0)
6272 return posix_error();
6273 Py_INCREF(Py_None);
6274 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006275}
6276#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006277
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006278#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6279static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006280wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006281{
Victor Stinner8c62be82010-05-06 00:08:46 +00006282 PyObject *result;
6283 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006284 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006285
Victor Stinner8c62be82010-05-06 00:08:46 +00006286 if (pid == -1)
6287 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006288
Victor Stinner8c62be82010-05-06 00:08:46 +00006289 if (struct_rusage == NULL) {
6290 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6291 if (m == NULL)
6292 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006293 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006294 Py_DECREF(m);
6295 if (struct_rusage == NULL)
6296 return NULL;
6297 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006298
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6300 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6301 if (!result)
6302 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006303
6304#ifndef doubletime
6305#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6306#endif
6307
Victor Stinner8c62be82010-05-06 00:08:46 +00006308 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006309 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006310 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006311 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006312#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6314 SET_INT(result, 2, ru->ru_maxrss);
6315 SET_INT(result, 3, ru->ru_ixrss);
6316 SET_INT(result, 4, ru->ru_idrss);
6317 SET_INT(result, 5, ru->ru_isrss);
6318 SET_INT(result, 6, ru->ru_minflt);
6319 SET_INT(result, 7, ru->ru_majflt);
6320 SET_INT(result, 8, ru->ru_nswap);
6321 SET_INT(result, 9, ru->ru_inblock);
6322 SET_INT(result, 10, ru->ru_oublock);
6323 SET_INT(result, 11, ru->ru_msgsnd);
6324 SET_INT(result, 12, ru->ru_msgrcv);
6325 SET_INT(result, 13, ru->ru_nsignals);
6326 SET_INT(result, 14, ru->ru_nvcsw);
6327 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006328#undef SET_INT
6329
Victor Stinner8c62be82010-05-06 00:08:46 +00006330 if (PyErr_Occurred()) {
6331 Py_DECREF(result);
6332 return NULL;
6333 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006334
Victor Stinner8c62be82010-05-06 00:08:46 +00006335 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006336}
6337#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6338
6339#ifdef HAVE_WAIT3
6340PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006341"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006342Wait for completion of a child process.");
6343
6344static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006345posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006346{
Victor Stinner8c62be82010-05-06 00:08:46 +00006347 pid_t pid;
6348 int options;
6349 struct rusage ru;
6350 WAIT_TYPE status;
6351 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006352
Victor Stinner4195b5c2012-02-08 23:03:19 +01006353 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006354 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006355
Victor Stinner8c62be82010-05-06 00:08:46 +00006356 Py_BEGIN_ALLOW_THREADS
6357 pid = wait3(&status, options, &ru);
6358 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006359
Victor Stinner4195b5c2012-02-08 23:03:19 +01006360 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006361}
6362#endif /* HAVE_WAIT3 */
6363
6364#ifdef HAVE_WAIT4
6365PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006366"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006367Wait for completion of a given child process.");
6368
6369static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006370posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006371{
Victor Stinner8c62be82010-05-06 00:08:46 +00006372 pid_t pid;
6373 int options;
6374 struct rusage ru;
6375 WAIT_TYPE status;
6376 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006377
Victor Stinner4195b5c2012-02-08 23:03:19 +01006378 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006379 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006380
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 Py_BEGIN_ALLOW_THREADS
6382 pid = wait4(pid, &status, options, &ru);
6383 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006384
Victor Stinner4195b5c2012-02-08 23:03:19 +01006385 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006386}
6387#endif /* HAVE_WAIT4 */
6388
Ross Lagerwall7807c352011-03-17 20:20:30 +02006389#if defined(HAVE_WAITID) && !defined(__APPLE__)
6390PyDoc_STRVAR(posix_waitid__doc__,
6391"waitid(idtype, id, options) -> waitid_result\n\n\
6392Wait for the completion of one or more child processes.\n\n\
6393idtype can be P_PID, P_PGID or P_ALL.\n\
6394id specifies the pid to wait on.\n\
6395options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6396or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6397Returns either waitid_result or None if WNOHANG is specified and there are\n\
6398no children in a waitable state.");
6399
6400static PyObject *
6401posix_waitid(PyObject *self, PyObject *args)
6402{
6403 PyObject *result;
6404 idtype_t idtype;
6405 id_t id;
6406 int options, res;
6407 siginfo_t si;
6408 si.si_pid = 0;
6409 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6410 return NULL;
6411 Py_BEGIN_ALLOW_THREADS
6412 res = waitid(idtype, id, &si, options);
6413 Py_END_ALLOW_THREADS
6414 if (res == -1)
6415 return posix_error();
6416
6417 if (si.si_pid == 0)
6418 Py_RETURN_NONE;
6419
6420 result = PyStructSequence_New(&WaitidResultType);
6421 if (!result)
6422 return NULL;
6423
6424 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6425 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6426 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6427 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6428 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6429 if (PyErr_Occurred()) {
6430 Py_DECREF(result);
6431 return NULL;
6432 }
6433
6434 return result;
6435}
6436#endif
6437
Guido van Rossumb6775db1994-08-01 11:34:53 +00006438#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006439PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006440"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006441Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006442
Barry Warsaw53699e91996-12-10 23:23:01 +00006443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006444posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006445{
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 pid_t pid;
6447 int options;
6448 WAIT_TYPE status;
6449 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006450
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6452 return NULL;
6453 Py_BEGIN_ALLOW_THREADS
6454 pid = waitpid(pid, &status, options);
6455 Py_END_ALLOW_THREADS
6456 if (pid == -1)
6457 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006458
Victor Stinner8c62be82010-05-06 00:08:46 +00006459 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006460}
6461
Tim Petersab034fa2002-02-01 11:27:43 +00006462#elif defined(HAVE_CWAIT)
6463
6464/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006465PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006466"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006467"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006468
6469static PyObject *
6470posix_waitpid(PyObject *self, PyObject *args)
6471{
Victor Stinner8c62be82010-05-06 00:08:46 +00006472 Py_intptr_t pid;
6473 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006474
Victor Stinner8c62be82010-05-06 00:08:46 +00006475 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6476 return NULL;
6477 Py_BEGIN_ALLOW_THREADS
6478 pid = _cwait(&status, pid, options);
6479 Py_END_ALLOW_THREADS
6480 if (pid == -1)
6481 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006482
Victor Stinner8c62be82010-05-06 00:08:46 +00006483 /* shift the status left a byte so this is more like the POSIX waitpid */
6484 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006485}
6486#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006487
Guido van Rossumad0ee831995-03-01 10:34:45 +00006488#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006489PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006490"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006491Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006492
Barry Warsaw53699e91996-12-10 23:23:01 +00006493static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006494posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006495{
Victor Stinner8c62be82010-05-06 00:08:46 +00006496 pid_t pid;
6497 WAIT_TYPE status;
6498 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006499
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 Py_BEGIN_ALLOW_THREADS
6501 pid = wait(&status);
6502 Py_END_ALLOW_THREADS
6503 if (pid == -1)
6504 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006505
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006507}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006508#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006509
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006510
Larry Hastings9cf065c2012-06-22 16:30:09 -07006511#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6512PyDoc_STRVAR(readlink__doc__,
6513"readlink(path, *, dir_fd=None) -> path\n\n\
6514Return a string representing the path to which the symbolic link points.\n\
6515\n\
6516If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6517 and path should be relative; path will then be relative to that directory.\n\
6518dir_fd may not be implemented on your platform.\n\
6519 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006520#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006521
Guido van Rossumb6775db1994-08-01 11:34:53 +00006522#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006523
Barry Warsaw53699e91996-12-10 23:23:01 +00006524static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006525posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006526{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006527 path_t path;
6528 int dir_fd = DEFAULT_DIR_FD;
6529 char buffer[MAXPATHLEN];
6530 ssize_t length;
6531 PyObject *return_value = NULL;
6532 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006533
Larry Hastings9cf065c2012-06-22 16:30:09 -07006534 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006535 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006536 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6537 path_converter, &path,
6538#ifdef HAVE_READLINKAT
6539 dir_fd_converter, &dir_fd
6540#else
6541 dir_fd_unavailable, &dir_fd
6542#endif
6543 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006545
Victor Stinner8c62be82010-05-06 00:08:46 +00006546 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006547#ifdef HAVE_READLINKAT
6548 if (dir_fd != DEFAULT_DIR_FD)
6549 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006550 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006551#endif
6552 length = readlink(path.narrow, buffer, sizeof(buffer));
6553 Py_END_ALLOW_THREADS
6554
6555 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006556 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006557 goto exit;
6558 }
6559
6560 if (PyUnicode_Check(path.object))
6561 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6562 else
6563 return_value = PyBytes_FromStringAndSize(buffer, length);
6564exit:
6565 path_cleanup(&path);
6566 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006567}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006568
6569
Guido van Rossumb6775db1994-08-01 11:34:53 +00006570#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006571
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006572
Larry Hastings9cf065c2012-06-22 16:30:09 -07006573#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006574PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006575"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
6576Create a symbolic link pointing to src named dst.\n\n\
6577target_is_directory is required on Windows if the target is to be\n\
6578 interpreted as a directory. (On Windows, symlink requires\n\
6579 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
6580 target_is_directory is ignored on non-Windows platforms.\n\
6581\n\
6582If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6583 and path should be relative; path will then be relative to that directory.\n\
6584dir_fd may not be implemented on your platform.\n\
6585 If it is unavailable, using it will raise a NotImplementedError.");
6586
6587#if defined(MS_WINDOWS)
6588
6589/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6590static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
6591static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
6592static int
6593check_CreateSymbolicLink()
6594{
6595 HINSTANCE hKernel32;
6596 /* only recheck */
6597 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
6598 return 1;
6599 hKernel32 = GetModuleHandleW(L"KERNEL32");
6600 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6601 "CreateSymbolicLinkW");
6602 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
6603 "CreateSymbolicLinkA");
6604 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
6605}
6606
6607#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006608
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006609static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006610posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006611{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006612 path_t src;
6613 path_t dst;
6614 int dir_fd = DEFAULT_DIR_FD;
6615 int target_is_directory = 0;
6616 static char *keywords[] = {"src", "dst", "target_is_directory",
6617 "dir_fd", NULL};
6618 PyObject *return_value;
6619#ifdef MS_WINDOWS
6620 DWORD result;
6621#else
6622 int result;
6623#endif
6624
6625 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01006626 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006627 src.argument_name = "src";
6628 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01006629 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006630 dst.argument_name = "dst";
6631
6632#ifdef MS_WINDOWS
6633 if (!check_CreateSymbolicLink()) {
6634 PyErr_SetString(PyExc_NotImplementedError,
6635 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006636 return NULL;
6637 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006638 if (!win32_can_symlink) {
6639 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006640 return NULL;
6641 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006642#endif
6643
6644 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
6645 keywords,
6646 path_converter, &src,
6647 path_converter, &dst,
6648 &target_is_directory,
6649#ifdef HAVE_SYMLINKAT
6650 dir_fd_converter, &dir_fd
6651#else
6652 dir_fd_unavailable, &dir_fd
6653#endif
6654 ))
6655 return NULL;
6656
6657 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
6658 PyErr_SetString(PyExc_ValueError,
6659 "symlink: src and dst must be the same type");
6660 return_value = NULL;
6661 goto exit;
6662 }
6663
6664#ifdef MS_WINDOWS
6665 Py_BEGIN_ALLOW_THREADS
6666 if (dst.wide)
6667 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
6668 target_is_directory);
6669 else
6670 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
6671 target_is_directory);
6672 Py_END_ALLOW_THREADS
6673
6674 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01006675 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006676 goto exit;
6677 }
6678
6679#else
6680
6681 Py_BEGIN_ALLOW_THREADS
6682#if HAVE_SYMLINKAT
6683 if (dir_fd != DEFAULT_DIR_FD)
6684 result = symlinkat(src.narrow, dir_fd, dst.narrow);
6685 else
6686#endif
6687 result = symlink(src.narrow, dst.narrow);
6688 Py_END_ALLOW_THREADS
6689
6690 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01006691 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006692 goto exit;
6693 }
6694#endif
6695
6696 return_value = Py_None;
6697 Py_INCREF(Py_None);
6698 goto exit; /* silence "unused label" warning */
6699exit:
6700 path_cleanup(&src);
6701 path_cleanup(&dst);
6702 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006703}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006704
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006705#endif /* HAVE_SYMLINK */
6706
Larry Hastings9cf065c2012-06-22 16:30:09 -07006707
Brian Curtind40e6f72010-07-08 21:39:08 +00006708#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6709
Brian Curtind40e6f72010-07-08 21:39:08 +00006710static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006711win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00006712{
6713 wchar_t *path;
6714 DWORD n_bytes_returned;
6715 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006716 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006717 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00006718 HANDLE reparse_point_handle;
6719
6720 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6721 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6722 wchar_t *print_name;
6723
Larry Hastings9cf065c2012-06-22 16:30:09 -07006724 static char *keywords[] = {"path", "dir_fd", NULL};
6725
6726 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
6727 &po,
6728 dir_fd_unavailable, &dir_fd
6729 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02006730 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006731
Victor Stinnereb5657a2011-09-30 01:44:27 +02006732 path = PyUnicode_AsUnicode(po);
6733 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006734 return NULL;
6735
6736 /* First get a handle to the reparse point */
6737 Py_BEGIN_ALLOW_THREADS
6738 reparse_point_handle = CreateFileW(
6739 path,
6740 0,
6741 0,
6742 0,
6743 OPEN_EXISTING,
6744 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6745 0);
6746 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006747
Brian Curtind40e6f72010-07-08 21:39:08 +00006748 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006749 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006750
Brian Curtind40e6f72010-07-08 21:39:08 +00006751 Py_BEGIN_ALLOW_THREADS
6752 /* New call DeviceIoControl to read the reparse point */
6753 io_result = DeviceIoControl(
6754 reparse_point_handle,
6755 FSCTL_GET_REPARSE_POINT,
6756 0, 0, /* in buffer */
6757 target_buffer, sizeof(target_buffer),
6758 &n_bytes_returned,
6759 0 /* we're not using OVERLAPPED_IO */
6760 );
6761 CloseHandle(reparse_point_handle);
6762 Py_END_ALLOW_THREADS
6763
6764 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006765 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006766
6767 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6768 {
6769 PyErr_SetString(PyExc_ValueError,
6770 "not a symbolic link");
6771 return NULL;
6772 }
Brian Curtin74e45612010-07-09 15:58:59 +00006773 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6774 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6775
6776 result = PyUnicode_FromWideChar(print_name,
6777 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006778 return result;
6779}
6780
6781#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6782
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006783
Larry Hastings605a62d2012-06-24 04:33:36 -07006784static PyStructSequence_Field times_result_fields[] = {
6785 {"user", "user time"},
6786 {"system", "system time"},
6787 {"children_user", "user time of children"},
6788 {"children_system", "system time of children"},
6789 {"elapsed", "elapsed time since an arbitrary point in the past"},
6790 {NULL}
6791};
6792
6793PyDoc_STRVAR(times_result__doc__,
6794"times_result: Result from os.times().\n\n\
6795This object may be accessed either as a tuple of\n\
6796 (user, system, children_user, children_system, elapsed),\n\
6797or via the attributes user, system, children_user, children_system,\n\
6798and elapsed.\n\
6799\n\
6800See os.times for more information.");
6801
6802static PyStructSequence_Desc times_result_desc = {
6803 "times_result", /* name */
6804 times_result__doc__, /* doc */
6805 times_result_fields,
6806 5
6807};
6808
6809static PyTypeObject TimesResultType;
6810
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006811#ifdef MS_WINDOWS
6812#define HAVE_TIMES /* mandatory, for the method table */
6813#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07006814
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006815#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07006816
6817static PyObject *
6818build_times_result(double user, double system,
6819 double children_user, double children_system,
6820 double elapsed)
6821{
6822 PyObject *value = PyStructSequence_New(&TimesResultType);
6823 if (value == NULL)
6824 return NULL;
6825
6826#define SET(i, field) \
6827 { \
6828 PyObject *o = PyFloat_FromDouble(field); \
6829 if (!o) { \
6830 Py_DECREF(value); \
6831 return NULL; \
6832 } \
6833 PyStructSequence_SET_ITEM(value, i, o); \
6834 } \
6835
6836 SET(0, user);
6837 SET(1, system);
6838 SET(2, children_user);
6839 SET(3, children_system);
6840 SET(4, elapsed);
6841
6842#undef SET
6843
6844 return value;
6845}
6846
6847PyDoc_STRVAR(posix_times__doc__,
6848"times() -> times_result\n\n\
6849Return an object containing floating point numbers indicating process\n\
6850times. The object behaves like a named tuple with these fields:\n\
6851 (utime, stime, cutime, cstime, elapsed_time)");
6852
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006853#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00006854static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006855posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006856{
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 FILETIME create, exit, kernel, user;
6858 HANDLE hProc;
6859 hProc = GetCurrentProcess();
6860 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6861 /* The fields of a FILETIME structure are the hi and lo part
6862 of a 64-bit value expressed in 100 nanosecond units.
6863 1e7 is one second in such units; 1e-7 the inverse.
6864 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6865 */
Larry Hastings605a62d2012-06-24 04:33:36 -07006866 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 (double)(user.dwHighDateTime*429.4967296 +
6868 user.dwLowDateTime*1e-7),
6869 (double)(kernel.dwHighDateTime*429.4967296 +
6870 kernel.dwLowDateTime*1e-7),
6871 (double)0,
6872 (double)0,
6873 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006874}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006875#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006876#define NEED_TICKS_PER_SECOND
6877static long ticks_per_second = -1;
6878static PyObject *
6879posix_times(PyObject *self, PyObject *noargs)
6880{
6881 struct tms t;
6882 clock_t c;
6883 errno = 0;
6884 c = times(&t);
6885 if (c == (clock_t) -1)
6886 return posix_error();
6887 return build_times_result(
6888 (double)t.tms_utime / ticks_per_second,
6889 (double)t.tms_stime / ticks_per_second,
6890 (double)t.tms_cutime / ticks_per_second,
6891 (double)t.tms_cstime / ticks_per_second,
6892 (double)c / ticks_per_second);
6893}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006894#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006895
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006896#endif /* HAVE_TIMES */
6897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006898
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006899#ifdef HAVE_GETSID
6900PyDoc_STRVAR(posix_getsid__doc__,
6901"getsid(pid) -> sid\n\n\
6902Call the system call getsid().");
6903
6904static PyObject *
6905posix_getsid(PyObject *self, PyObject *args)
6906{
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 pid_t pid;
6908 int sid;
6909 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6910 return NULL;
6911 sid = getsid(pid);
6912 if (sid < 0)
6913 return posix_error();
6914 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006915}
6916#endif /* HAVE_GETSID */
6917
6918
Guido van Rossumb6775db1994-08-01 11:34:53 +00006919#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006920PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006921"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006922Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006923
Barry Warsaw53699e91996-12-10 23:23:01 +00006924static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006925posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006926{
Victor Stinner8c62be82010-05-06 00:08:46 +00006927 if (setsid() < 0)
6928 return posix_error();
6929 Py_INCREF(Py_None);
6930 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006931}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006932#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006933
Guido van Rossumb6775db1994-08-01 11:34:53 +00006934#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006935PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006936"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006937Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006938
Barry Warsaw53699e91996-12-10 23:23:01 +00006939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006940posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006941{
Victor Stinner8c62be82010-05-06 00:08:46 +00006942 pid_t pid;
6943 int pgrp;
6944 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6945 return NULL;
6946 if (setpgid(pid, pgrp) < 0)
6947 return posix_error();
6948 Py_INCREF(Py_None);
6949 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006950}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006951#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006952
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006953
Guido van Rossumb6775db1994-08-01 11:34:53 +00006954#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006955PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006956"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006957Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006958
Barry Warsaw53699e91996-12-10 23:23:01 +00006959static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006960posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006961{
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 int fd;
6963 pid_t pgid;
6964 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6965 return NULL;
6966 pgid = tcgetpgrp(fd);
6967 if (pgid < 0)
6968 return posix_error();
6969 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006970}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006971#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006972
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006973
Guido van Rossumb6775db1994-08-01 11:34:53 +00006974#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006975PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006976"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006977Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006978
Barry Warsaw53699e91996-12-10 23:23:01 +00006979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006980posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006981{
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 int fd;
6983 pid_t pgid;
6984 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6985 return NULL;
6986 if (tcsetpgrp(fd, pgid) < 0)
6987 return posix_error();
6988 Py_INCREF(Py_None);
6989 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006990}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006991#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006992
Guido van Rossum687dd131993-05-17 08:34:16 +00006993/* Functions acting on file descriptors */
6994
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006995PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006996"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
6997Open a file for low level IO. Returns a file handle (integer).\n\
6998\n\
6999If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7000 and path should be relative; path will then be relative to that directory.\n\
7001dir_fd may not be implemented on your platform.\n\
7002 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007003
Barry Warsaw53699e91996-12-10 23:23:01 +00007004static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007005posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007006{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007007 path_t path;
7008 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007010 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007011 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007012 PyObject *return_value = NULL;
7013 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007014
Larry Hastings9cf065c2012-06-22 16:30:09 -07007015 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007016 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007017 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7018 path_converter, &path,
7019 &flags, &mode,
7020#ifdef HAVE_OPENAT
7021 dir_fd_converter, &dir_fd
7022#else
7023 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007024#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007025 ))
7026 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007027
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007029#ifdef MS_WINDOWS
7030 if (path.wide)
7031 fd = _wopen(path.wide, flags, mode);
7032 else
7033#endif
7034#ifdef HAVE_OPENAT
7035 if (dir_fd != DEFAULT_DIR_FD)
7036 fd = openat(dir_fd, path.narrow, flags, mode);
7037 else
7038#endif
7039 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007040 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007041
Larry Hastings9cf065c2012-06-22 16:30:09 -07007042 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007043 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007044 goto exit;
7045 }
7046
7047 return_value = PyLong_FromLong((long)fd);
7048
7049exit:
7050 path_cleanup(&path);
7051 return return_value;
7052}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007053
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007054PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007055"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007056Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007057
Barry Warsaw53699e91996-12-10 23:23:01 +00007058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007059posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007060{
Victor Stinner8c62be82010-05-06 00:08:46 +00007061 int fd, res;
7062 if (!PyArg_ParseTuple(args, "i:close", &fd))
7063 return NULL;
7064 if (!_PyVerify_fd(fd))
7065 return posix_error();
7066 Py_BEGIN_ALLOW_THREADS
7067 res = close(fd);
7068 Py_END_ALLOW_THREADS
7069 if (res < 0)
7070 return posix_error();
7071 Py_INCREF(Py_None);
7072 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007073}
7074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007075
Victor Stinner8c62be82010-05-06 00:08:46 +00007076PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007077"closerange(fd_low, fd_high)\n\n\
7078Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7079
7080static PyObject *
7081posix_closerange(PyObject *self, PyObject *args)
7082{
Victor Stinner8c62be82010-05-06 00:08:46 +00007083 int fd_from, fd_to, i;
7084 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7085 return NULL;
7086 Py_BEGIN_ALLOW_THREADS
7087 for (i = fd_from; i < fd_to; i++)
7088 if (_PyVerify_fd(i))
7089 close(i);
7090 Py_END_ALLOW_THREADS
7091 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007092}
7093
7094
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007095PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007096"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007097Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007098
Barry Warsaw53699e91996-12-10 23:23:01 +00007099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007100posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007101{
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 int fd;
7103 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7104 return NULL;
7105 if (!_PyVerify_fd(fd))
7106 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007107 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 if (fd < 0)
7109 return posix_error();
7110 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007111}
7112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007113
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007114PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007115"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007116Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007117
Barry Warsaw53699e91996-12-10 23:23:01 +00007118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007119posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007120{
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 int fd, fd2, res;
7122 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7123 return NULL;
7124 if (!_PyVerify_fd_dup2(fd, fd2))
7125 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 if (res < 0)
7128 return posix_error();
7129 Py_INCREF(Py_None);
7130 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007131}
7132
Ross Lagerwall7807c352011-03-17 20:20:30 +02007133#ifdef HAVE_LOCKF
7134PyDoc_STRVAR(posix_lockf__doc__,
7135"lockf(fd, cmd, len)\n\n\
7136Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7137fd is an open file descriptor.\n\
7138cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7139F_TEST.\n\
7140len specifies the section of the file to lock.");
7141
7142static PyObject *
7143posix_lockf(PyObject *self, PyObject *args)
7144{
7145 int fd, cmd, res;
7146 off_t len;
7147 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7148 &fd, &cmd, _parse_off_t, &len))
7149 return NULL;
7150
7151 Py_BEGIN_ALLOW_THREADS
7152 res = lockf(fd, cmd, len);
7153 Py_END_ALLOW_THREADS
7154
7155 if (res < 0)
7156 return posix_error();
7157
7158 Py_RETURN_NONE;
7159}
7160#endif
7161
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007162
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007163PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007164"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007165Set the current position of a file descriptor.\n\
7166Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007167
Barry Warsaw53699e91996-12-10 23:23:01 +00007168static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007169posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007170{
Victor Stinner8c62be82010-05-06 00:08:46 +00007171 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007172#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007173 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007174#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007175 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007176#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007177 PyObject *posobj;
7178 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007179 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007180#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007181 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7182 switch (how) {
7183 case 0: how = SEEK_SET; break;
7184 case 1: how = SEEK_CUR; break;
7185 case 2: how = SEEK_END; break;
7186 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007187#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007188
Ross Lagerwall8e749672011-03-17 21:54:07 +02007189#if !defined(HAVE_LARGEFILE_SUPPORT)
7190 pos = PyLong_AsLong(posobj);
7191#else
7192 pos = PyLong_AsLongLong(posobj);
7193#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007194 if (PyErr_Occurred())
7195 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007196
Victor Stinner8c62be82010-05-06 00:08:46 +00007197 if (!_PyVerify_fd(fd))
7198 return posix_error();
7199 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007200#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007201 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007202#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007203 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007204#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007205 Py_END_ALLOW_THREADS
7206 if (res < 0)
7207 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007208
7209#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007210 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007211#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007212 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007213#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007214}
7215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007216
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007217PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007218"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007219Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007220
Barry Warsaw53699e91996-12-10 23:23:01 +00007221static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007222posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007223{
Victor Stinner8c62be82010-05-06 00:08:46 +00007224 int fd, size;
7225 Py_ssize_t n;
7226 PyObject *buffer;
7227 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7228 return NULL;
7229 if (size < 0) {
7230 errno = EINVAL;
7231 return posix_error();
7232 }
7233 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7234 if (buffer == NULL)
7235 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007236 if (!_PyVerify_fd(fd)) {
7237 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007238 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007239 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 Py_BEGIN_ALLOW_THREADS
7241 n = read(fd, PyBytes_AS_STRING(buffer), size);
7242 Py_END_ALLOW_THREADS
7243 if (n < 0) {
7244 Py_DECREF(buffer);
7245 return posix_error();
7246 }
7247 if (n != size)
7248 _PyBytes_Resize(&buffer, n);
7249 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007250}
7251
Ross Lagerwall7807c352011-03-17 20:20:30 +02007252#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7253 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007254static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007255iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7256{
7257 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007258 Py_ssize_t blen, total = 0;
7259
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007260 *iov = PyMem_New(struct iovec, cnt);
7261 if (*iov == NULL) {
7262 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007263 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007264 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007265
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007266 *buf = PyMem_New(Py_buffer, cnt);
7267 if (*buf == NULL) {
7268 PyMem_Del(*iov);
7269 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007270 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007271 }
7272
7273 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007274 PyObject *item = PySequence_GetItem(seq, i);
7275 if (item == NULL)
7276 goto fail;
7277 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7278 Py_DECREF(item);
7279 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007280 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007281 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007282 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007283 blen = (*buf)[i].len;
7284 (*iov)[i].iov_len = blen;
7285 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007286 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007287 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007288
7289fail:
7290 PyMem_Del(*iov);
7291 for (j = 0; j < i; j++) {
7292 PyBuffer_Release(&(*buf)[j]);
7293 }
7294 PyMem_Del(*buf);
7295 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007296}
7297
7298static void
7299iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7300{
7301 int i;
7302 PyMem_Del(iov);
7303 for (i = 0; i < cnt; i++) {
7304 PyBuffer_Release(&buf[i]);
7305 }
7306 PyMem_Del(buf);
7307}
7308#endif
7309
Ross Lagerwall7807c352011-03-17 20:20:30 +02007310#ifdef HAVE_READV
7311PyDoc_STRVAR(posix_readv__doc__,
7312"readv(fd, buffers) -> bytesread\n\n\
7313Read from a file descriptor into a number of writable buffers. buffers\n\
7314is an arbitrary sequence of writable buffers.\n\
7315Returns the total number of bytes read.");
7316
7317static PyObject *
7318posix_readv(PyObject *self, PyObject *args)
7319{
7320 int fd, cnt;
7321 Py_ssize_t n;
7322 PyObject *seq;
7323 struct iovec *iov;
7324 Py_buffer *buf;
7325
7326 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7327 return NULL;
7328 if (!PySequence_Check(seq)) {
7329 PyErr_SetString(PyExc_TypeError,
7330 "readv() arg 2 must be a sequence");
7331 return NULL;
7332 }
7333 cnt = PySequence_Size(seq);
7334
7335 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7336 return NULL;
7337
7338 Py_BEGIN_ALLOW_THREADS
7339 n = readv(fd, iov, cnt);
7340 Py_END_ALLOW_THREADS
7341
7342 iov_cleanup(iov, buf, cnt);
7343 return PyLong_FromSsize_t(n);
7344}
7345#endif
7346
7347#ifdef HAVE_PREAD
7348PyDoc_STRVAR(posix_pread__doc__,
7349"pread(fd, buffersize, offset) -> string\n\n\
7350Read from a file descriptor, fd, at a position of offset. It will read up\n\
7351to buffersize number of bytes. The file offset remains unchanged.");
7352
7353static PyObject *
7354posix_pread(PyObject *self, PyObject *args)
7355{
7356 int fd, size;
7357 off_t offset;
7358 Py_ssize_t n;
7359 PyObject *buffer;
7360 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7361 return NULL;
7362
7363 if (size < 0) {
7364 errno = EINVAL;
7365 return posix_error();
7366 }
7367 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7368 if (buffer == NULL)
7369 return NULL;
7370 if (!_PyVerify_fd(fd)) {
7371 Py_DECREF(buffer);
7372 return posix_error();
7373 }
7374 Py_BEGIN_ALLOW_THREADS
7375 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7376 Py_END_ALLOW_THREADS
7377 if (n < 0) {
7378 Py_DECREF(buffer);
7379 return posix_error();
7380 }
7381 if (n != size)
7382 _PyBytes_Resize(&buffer, n);
7383 return buffer;
7384}
7385#endif
7386
7387PyDoc_STRVAR(posix_write__doc__,
7388"write(fd, string) -> byteswritten\n\n\
7389Write a string to a file descriptor.");
7390
7391static PyObject *
7392posix_write(PyObject *self, PyObject *args)
7393{
7394 Py_buffer pbuf;
7395 int fd;
7396 Py_ssize_t size, len;
7397
7398 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7399 return NULL;
7400 if (!_PyVerify_fd(fd)) {
7401 PyBuffer_Release(&pbuf);
7402 return posix_error();
7403 }
7404 len = pbuf.len;
7405 Py_BEGIN_ALLOW_THREADS
7406#if defined(MS_WIN64) || defined(MS_WINDOWS)
7407 if (len > INT_MAX)
7408 len = INT_MAX;
7409 size = write(fd, pbuf.buf, (int)len);
7410#else
7411 size = write(fd, pbuf.buf, len);
7412#endif
7413 Py_END_ALLOW_THREADS
7414 PyBuffer_Release(&pbuf);
7415 if (size < 0)
7416 return posix_error();
7417 return PyLong_FromSsize_t(size);
7418}
7419
7420#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007421PyDoc_STRVAR(posix_sendfile__doc__,
7422"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7423sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7424 -> byteswritten\n\
7425Copy nbytes bytes from file descriptor in to file descriptor out.");
7426
7427static PyObject *
7428posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7429{
7430 int in, out;
7431 Py_ssize_t ret;
7432 off_t offset;
7433
7434#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7435#ifndef __APPLE__
7436 Py_ssize_t len;
7437#endif
7438 PyObject *headers = NULL, *trailers = NULL;
7439 Py_buffer *hbuf, *tbuf;
7440 off_t sbytes;
7441 struct sf_hdtr sf;
7442 int flags = 0;
7443 sf.headers = NULL;
7444 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007445 static char *keywords[] = {"out", "in",
7446 "offset", "count",
7447 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007448
7449#ifdef __APPLE__
7450 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007451 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007452#else
7453 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007454 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007455#endif
7456 &headers, &trailers, &flags))
7457 return NULL;
7458 if (headers != NULL) {
7459 if (!PySequence_Check(headers)) {
7460 PyErr_SetString(PyExc_TypeError,
7461 "sendfile() headers must be a sequence or None");
7462 return NULL;
7463 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007464 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007465 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007466 if (sf.hdr_cnt > 0 &&
7467 !(i = iov_setup(&(sf.headers), &hbuf,
7468 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007469 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007470#ifdef __APPLE__
7471 sbytes += i;
7472#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007473 }
7474 }
7475 if (trailers != NULL) {
7476 if (!PySequence_Check(trailers)) {
7477 PyErr_SetString(PyExc_TypeError,
7478 "sendfile() trailers must be a sequence or None");
7479 return NULL;
7480 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007481 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007482 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007483 if (sf.trl_cnt > 0 &&
7484 !(i = iov_setup(&(sf.trailers), &tbuf,
7485 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007486 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007487#ifdef __APPLE__
7488 sbytes += i;
7489#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007490 }
7491 }
7492
7493 Py_BEGIN_ALLOW_THREADS
7494#ifdef __APPLE__
7495 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7496#else
7497 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7498#endif
7499 Py_END_ALLOW_THREADS
7500
7501 if (sf.headers != NULL)
7502 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7503 if (sf.trailers != NULL)
7504 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7505
7506 if (ret < 0) {
7507 if ((errno == EAGAIN) || (errno == EBUSY)) {
7508 if (sbytes != 0) {
7509 // some data has been sent
7510 goto done;
7511 }
7512 else {
7513 // no data has been sent; upper application is supposed
7514 // to retry on EAGAIN or EBUSY
7515 return posix_error();
7516 }
7517 }
7518 return posix_error();
7519 }
7520 goto done;
7521
7522done:
7523 #if !defined(HAVE_LARGEFILE_SUPPORT)
7524 return Py_BuildValue("l", sbytes);
7525 #else
7526 return Py_BuildValue("L", sbytes);
7527 #endif
7528
7529#else
7530 Py_ssize_t count;
7531 PyObject *offobj;
7532 static char *keywords[] = {"out", "in",
7533 "offset", "count", NULL};
7534 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7535 keywords, &out, &in, &offobj, &count))
7536 return NULL;
7537#ifdef linux
7538 if (offobj == Py_None) {
7539 Py_BEGIN_ALLOW_THREADS
7540 ret = sendfile(out, in, NULL, count);
7541 Py_END_ALLOW_THREADS
7542 if (ret < 0)
7543 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007544 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007545 }
7546#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007547 if (!_parse_off_t(offobj, &offset))
7548 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007549 Py_BEGIN_ALLOW_THREADS
7550 ret = sendfile(out, in, &offset, count);
7551 Py_END_ALLOW_THREADS
7552 if (ret < 0)
7553 return posix_error();
7554 return Py_BuildValue("n", ret);
7555#endif
7556}
7557#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007558
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007559PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007560"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007561Like stat(), but for an open file descriptor.\n\
7562Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007563
Barry Warsaw53699e91996-12-10 23:23:01 +00007564static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007565posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007566{
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 int fd;
7568 STRUCT_STAT st;
7569 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007570 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007571 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007572#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007573 /* on OpenVMS we must ensure that all bytes are written to the file */
7574 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007575#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007576 Py_BEGIN_ALLOW_THREADS
7577 res = FSTAT(fd, &st);
7578 Py_END_ALLOW_THREADS
7579 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007580#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01007581 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00007582#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007583 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007584#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007585 }
Tim Peters5aa91602002-01-30 05:46:57 +00007586
Victor Stinner4195b5c2012-02-08 23:03:19 +01007587 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007588}
7589
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007590PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007591"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007592Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007593connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007594
7595static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007596posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007597{
Victor Stinner8c62be82010-05-06 00:08:46 +00007598 int fd;
7599 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7600 return NULL;
7601 if (!_PyVerify_fd(fd))
7602 return PyBool_FromLong(0);
7603 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007604}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007605
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007606#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007607PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007608"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007609Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007610
Barry Warsaw53699e91996-12-10 23:23:01 +00007611static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007612posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007613{
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007614#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007615 int fds[2];
7616 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007617 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 if (res != 0)
7619 return posix_error();
7620 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007621#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007622 HANDLE read, write;
7623 int read_fd, write_fd;
7624 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01007627 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007628 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7629 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7630 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007631#endif /* MS_WINDOWS */
Guido van Rossum687dd131993-05-17 08:34:16 +00007632}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007633#endif /* HAVE_PIPE */
7634
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007635#ifdef HAVE_PIPE2
7636PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007637"pipe2(flags) -> (read_end, write_end)\n\n\
7638Create a pipe with flags set atomically.\n\
7639flags can be constructed by ORing together one or more of these values:\n\
7640O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007641");
7642
7643static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007644posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007645{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007646 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007647 int fds[2];
7648 int res;
7649
Serhiy Storchaka78980432013-01-15 01:12:17 +02007650 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02007651 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007652 return NULL;
7653
7654 res = pipe2(fds, flags);
7655 if (res != 0)
7656 return posix_error();
7657 return Py_BuildValue("(ii)", fds[0], fds[1]);
7658}
7659#endif /* HAVE_PIPE2 */
7660
Ross Lagerwall7807c352011-03-17 20:20:30 +02007661#ifdef HAVE_WRITEV
7662PyDoc_STRVAR(posix_writev__doc__,
7663"writev(fd, buffers) -> byteswritten\n\n\
7664Write the contents of buffers to a file descriptor, where buffers is an\n\
7665arbitrary sequence of buffers.\n\
7666Returns the total bytes written.");
7667
7668static PyObject *
7669posix_writev(PyObject *self, PyObject *args)
7670{
7671 int fd, cnt;
7672 Py_ssize_t res;
7673 PyObject *seq;
7674 struct iovec *iov;
7675 Py_buffer *buf;
7676 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7677 return NULL;
7678 if (!PySequence_Check(seq)) {
7679 PyErr_SetString(PyExc_TypeError,
7680 "writev() arg 2 must be a sequence");
7681 return NULL;
7682 }
7683 cnt = PySequence_Size(seq);
7684
7685 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7686 return NULL;
7687 }
7688
7689 Py_BEGIN_ALLOW_THREADS
7690 res = writev(fd, iov, cnt);
7691 Py_END_ALLOW_THREADS
7692
7693 iov_cleanup(iov, buf, cnt);
7694 return PyLong_FromSsize_t(res);
7695}
7696#endif
7697
7698#ifdef HAVE_PWRITE
7699PyDoc_STRVAR(posix_pwrite__doc__,
7700"pwrite(fd, string, offset) -> byteswritten\n\n\
7701Write string to a file descriptor, fd, from offset, leaving the file\n\
7702offset unchanged.");
7703
7704static PyObject *
7705posix_pwrite(PyObject *self, PyObject *args)
7706{
7707 Py_buffer pbuf;
7708 int fd;
7709 off_t offset;
7710 Py_ssize_t size;
7711
7712 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7713 return NULL;
7714
7715 if (!_PyVerify_fd(fd)) {
7716 PyBuffer_Release(&pbuf);
7717 return posix_error();
7718 }
7719 Py_BEGIN_ALLOW_THREADS
7720 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7721 Py_END_ALLOW_THREADS
7722 PyBuffer_Release(&pbuf);
7723 if (size < 0)
7724 return posix_error();
7725 return PyLong_FromSsize_t(size);
7726}
7727#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007728
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007729#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007730PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007731"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
7732Create a FIFO (a POSIX named pipe).\n\
7733\n\
7734If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7735 and path should be relative; path will then be relative to that directory.\n\
7736dir_fd may not be implemented on your platform.\n\
7737 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007738
Barry Warsaw53699e91996-12-10 23:23:01 +00007739static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007740posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007741{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007742 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007744 int dir_fd = DEFAULT_DIR_FD;
7745 int result;
7746 PyObject *return_value = NULL;
7747 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
7748
7749 memset(&path, 0, sizeof(path));
7750 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
7751 path_converter, &path,
7752 &mode,
7753#ifdef HAVE_MKFIFOAT
7754 dir_fd_converter, &dir_fd
7755#else
7756 dir_fd_unavailable, &dir_fd
7757#endif
7758 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007759 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007760
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007762#ifdef HAVE_MKFIFOAT
7763 if (dir_fd != DEFAULT_DIR_FD)
7764 result = mkfifoat(dir_fd, path.narrow, mode);
7765 else
7766#endif
7767 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007769
7770 if (result < 0) {
7771 return_value = posix_error();
7772 goto exit;
7773 }
7774
7775 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007776 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007777
7778exit:
7779 path_cleanup(&path);
7780 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007781}
7782#endif
7783
Neal Norwitz11690112002-07-30 01:08:28 +00007784#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007785PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007786"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007787Create a filesystem node (file, device special file or named pipe)\n\
7788named filename. mode specifies both the permissions to use and the\n\
7789type of node to be created, being combined (bitwise OR) with one of\n\
7790S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007791device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007792os.makedev()), otherwise it is ignored.\n\
7793\n\
7794If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7795 and path should be relative; path will then be relative to that directory.\n\
7796dir_fd may not be implemented on your platform.\n\
7797 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007798
7799
7800static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007801posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007802{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007803 path_t path;
7804 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00007805 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007806 int dir_fd = DEFAULT_DIR_FD;
7807 int result;
7808 PyObject *return_value = NULL;
7809 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
7810
7811 memset(&path, 0, sizeof(path));
7812 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
7813 path_converter, &path,
7814 &mode, &device,
7815#ifdef HAVE_MKNODAT
7816 dir_fd_converter, &dir_fd
7817#else
7818 dir_fd_unavailable, &dir_fd
7819#endif
7820 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007822
Victor Stinner8c62be82010-05-06 00:08:46 +00007823 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007824#ifdef HAVE_MKNODAT
7825 if (dir_fd != DEFAULT_DIR_FD)
7826 result = mknodat(dir_fd, path.narrow, mode, device);
7827 else
7828#endif
7829 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00007830 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007831
7832 if (result < 0) {
7833 return_value = posix_error();
7834 goto exit;
7835 }
7836
7837 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02007839
Larry Hastings9cf065c2012-06-22 16:30:09 -07007840exit:
7841 path_cleanup(&path);
7842 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007843}
7844#endif
7845
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007846#ifdef HAVE_DEVICE_MACROS
7847PyDoc_STRVAR(posix_major__doc__,
7848"major(device) -> major number\n\
7849Extracts a device major number from a raw device number.");
7850
7851static PyObject *
7852posix_major(PyObject *self, PyObject *args)
7853{
Victor Stinner8c62be82010-05-06 00:08:46 +00007854 int device;
7855 if (!PyArg_ParseTuple(args, "i:major", &device))
7856 return NULL;
7857 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007858}
7859
7860PyDoc_STRVAR(posix_minor__doc__,
7861"minor(device) -> minor number\n\
7862Extracts a device minor number from a raw device number.");
7863
7864static PyObject *
7865posix_minor(PyObject *self, PyObject *args)
7866{
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 int device;
7868 if (!PyArg_ParseTuple(args, "i:minor", &device))
7869 return NULL;
7870 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007871}
7872
7873PyDoc_STRVAR(posix_makedev__doc__,
7874"makedev(major, minor) -> device number\n\
7875Composes a raw device number from the major and minor device numbers.");
7876
7877static PyObject *
7878posix_makedev(PyObject *self, PyObject *args)
7879{
Victor Stinner8c62be82010-05-06 00:08:46 +00007880 int major, minor;
7881 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7882 return NULL;
7883 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007884}
7885#endif /* device macros */
7886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007887
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007888#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007889PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007890"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007891Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007892
Barry Warsaw53699e91996-12-10 23:23:01 +00007893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007894posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007895{
Victor Stinner8c62be82010-05-06 00:08:46 +00007896 int fd;
7897 off_t length;
7898 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007899
Ross Lagerwall7807c352011-03-17 20:20:30 +02007900 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007901 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007902
Victor Stinner8c62be82010-05-06 00:08:46 +00007903 Py_BEGIN_ALLOW_THREADS
7904 res = ftruncate(fd, length);
7905 Py_END_ALLOW_THREADS
7906 if (res < 0)
7907 return posix_error();
7908 Py_INCREF(Py_None);
7909 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007910}
7911#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007912
Ross Lagerwall7807c352011-03-17 20:20:30 +02007913#ifdef HAVE_TRUNCATE
7914PyDoc_STRVAR(posix_truncate__doc__,
7915"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02007916Truncate the file given by path to length bytes.\n\
7917On some platforms, path may also be specified as an open file descriptor.\n\
7918 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02007919
7920static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02007921posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02007922{
Georg Brandl306336b2012-06-24 12:55:33 +02007923 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007924 off_t length;
7925 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02007926 PyObject *result = NULL;
7927 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02007928
Georg Brandl306336b2012-06-24 12:55:33 +02007929 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007930 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02007931#ifdef HAVE_FTRUNCATE
7932 path.allow_fd = 1;
7933#endif
7934 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
7935 path_converter, &path,
7936 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02007937 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007938
7939 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02007940#ifdef HAVE_FTRUNCATE
7941 if (path.fd != -1)
7942 res = ftruncate(path.fd, length);
7943 else
7944#endif
7945 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007946 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02007947 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01007948 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02007949 else {
7950 Py_INCREF(Py_None);
7951 result = Py_None;
7952 }
7953 path_cleanup(&path);
7954 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007955}
7956#endif
7957
7958#ifdef HAVE_POSIX_FALLOCATE
7959PyDoc_STRVAR(posix_posix_fallocate__doc__,
7960"posix_fallocate(fd, offset, len)\n\n\
7961Ensures that enough disk space is allocated for the file specified by fd\n\
7962starting from offset and continuing for len bytes.");
7963
7964static PyObject *
7965posix_posix_fallocate(PyObject *self, PyObject *args)
7966{
7967 off_t len, offset;
7968 int res, fd;
7969
7970 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7971 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7972 return NULL;
7973
7974 Py_BEGIN_ALLOW_THREADS
7975 res = posix_fallocate(fd, offset, len);
7976 Py_END_ALLOW_THREADS
7977 if (res != 0) {
7978 errno = res;
7979 return posix_error();
7980 }
7981 Py_RETURN_NONE;
7982}
7983#endif
7984
7985#ifdef HAVE_POSIX_FADVISE
7986PyDoc_STRVAR(posix_posix_fadvise__doc__,
7987"posix_fadvise(fd, offset, len, advice)\n\n\
7988Announces an intention to access data in a specific pattern thus allowing\n\
7989the kernel to make optimizations.\n\
7990The advice applies to the region of the file specified by fd starting at\n\
7991offset and continuing for len bytes.\n\
7992advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7993POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7994POSIX_FADV_DONTNEED.");
7995
7996static PyObject *
7997posix_posix_fadvise(PyObject *self, PyObject *args)
7998{
7999 off_t len, offset;
8000 int res, fd, advice;
8001
8002 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8003 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8004 return NULL;
8005
8006 Py_BEGIN_ALLOW_THREADS
8007 res = posix_fadvise(fd, offset, len, advice);
8008 Py_END_ALLOW_THREADS
8009 if (res != 0) {
8010 errno = res;
8011 return posix_error();
8012 }
8013 Py_RETURN_NONE;
8014}
8015#endif
8016
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008017#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008018PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008019"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008020Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008021
Fred Drake762e2061999-08-26 17:23:54 +00008022/* Save putenv() parameters as values here, so we can collect them when they
8023 * get re-set with another call for the same key. */
8024static PyObject *posix_putenv_garbage;
8025
Tim Peters5aa91602002-01-30 05:46:57 +00008026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008027posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008028{
Victor Stinner84ae1182010-05-06 22:05:07 +00008029 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008030#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008031 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008032 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008033
Victor Stinner8c62be82010-05-06 00:08:46 +00008034 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008035 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008036 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008038
Victor Stinner65170952011-11-22 22:16:17 +01008039 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008040 if (newstr == NULL) {
8041 PyErr_NoMemory();
8042 goto error;
8043 }
Victor Stinner65170952011-11-22 22:16:17 +01008044 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8045 PyErr_Format(PyExc_ValueError,
8046 "the environment variable is longer than %u characters",
8047 _MAX_ENV);
8048 goto error;
8049 }
8050
Victor Stinner8c62be82010-05-06 00:08:46 +00008051 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008052 if (newenv == NULL)
8053 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008054 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008055 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008056 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008057 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008058#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008059 PyObject *os1, *os2;
8060 char *s1, *s2;
8061 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008062
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008063 if (!PyArg_ParseTuple(args,
8064 "O&O&:putenv",
8065 PyUnicode_FSConverter, &os1,
8066 PyUnicode_FSConverter, &os2))
8067 return NULL;
8068 s1 = PyBytes_AsString(os1);
8069 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008070
Victor Stinner65170952011-11-22 22:16:17 +01008071 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008072 if (newstr == NULL) {
8073 PyErr_NoMemory();
8074 goto error;
8075 }
8076
Victor Stinner8c62be82010-05-06 00:08:46 +00008077 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008079 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008080 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008081 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008082#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008083
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 /* Install the first arg and newstr in posix_putenv_garbage;
8085 * this will cause previous value to be collected. This has to
8086 * happen after the real putenv() call because the old value
8087 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008088 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008089 /* really not much we can do; just leak */
8090 PyErr_Clear();
8091 }
8092 else {
8093 Py_DECREF(newstr);
8094 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008095
Martin v. Löwis011e8422009-05-05 04:43:17 +00008096#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008097 Py_DECREF(os1);
8098 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008099#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008100 Py_RETURN_NONE;
8101
8102error:
8103#ifndef MS_WINDOWS
8104 Py_DECREF(os1);
8105 Py_DECREF(os2);
8106#endif
8107 Py_XDECREF(newstr);
8108 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008109}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008110#endif /* putenv */
8111
Guido van Rossumc524d952001-10-19 01:31:59 +00008112#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008113PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008114"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008115Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008116
8117static PyObject *
8118posix_unsetenv(PyObject *self, PyObject *args)
8119{
Victor Stinner65170952011-11-22 22:16:17 +01008120 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008121#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008122 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008123#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008124
8125 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008126
Victor Stinner65170952011-11-22 22:16:17 +01008127 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008128 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008129
Victor Stinner984890f2011-11-24 13:53:38 +01008130#ifdef HAVE_BROKEN_UNSETENV
8131 unsetenv(PyBytes_AS_STRING(name));
8132#else
Victor Stinner65170952011-11-22 22:16:17 +01008133 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008134 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008135 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008136 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008137 }
Victor Stinner984890f2011-11-24 13:53:38 +01008138#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008139
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 /* Remove the key from posix_putenv_garbage;
8141 * this will cause it to be collected. This has to
8142 * happen after the real unsetenv() call because the
8143 * old value was still accessible until then.
8144 */
Victor Stinner65170952011-11-22 22:16:17 +01008145 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008146 /* really not much we can do; just leak */
8147 PyErr_Clear();
8148 }
Victor Stinner65170952011-11-22 22:16:17 +01008149 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008150 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008151}
8152#endif /* unsetenv */
8153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008154PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008155"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008156Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008157
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008159posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008160{
Victor Stinner8c62be82010-05-06 00:08:46 +00008161 int code;
8162 char *message;
8163 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8164 return NULL;
8165 message = strerror(code);
8166 if (message == NULL) {
8167 PyErr_SetString(PyExc_ValueError,
8168 "strerror() argument out of range");
8169 return NULL;
8170 }
Victor Stinner1b579672011-12-17 05:47:23 +01008171 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008172}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008173
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008174
Guido van Rossumc9641791998-08-04 15:26:23 +00008175#ifdef HAVE_SYS_WAIT_H
8176
Fred Drake106c1a02002-04-23 15:58:02 +00008177#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008178PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008179"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008180Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008181
8182static PyObject *
8183posix_WCOREDUMP(PyObject *self, PyObject *args)
8184{
Victor Stinner8c62be82010-05-06 00:08:46 +00008185 WAIT_TYPE status;
8186 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008187
Victor Stinner8c62be82010-05-06 00:08:46 +00008188 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8189 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008190
Victor Stinner8c62be82010-05-06 00:08:46 +00008191 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008192}
8193#endif /* WCOREDUMP */
8194
8195#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008196PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008197"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008198Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008199job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008200
8201static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008202posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008203{
Victor Stinner8c62be82010-05-06 00:08:46 +00008204 WAIT_TYPE status;
8205 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008206
Victor Stinner8c62be82010-05-06 00:08:46 +00008207 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8208 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008209
Victor Stinner8c62be82010-05-06 00:08:46 +00008210 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008211}
8212#endif /* WIFCONTINUED */
8213
Guido van Rossumc9641791998-08-04 15:26:23 +00008214#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008215PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008216"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008217Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008218
8219static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008220posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008221{
Victor Stinner8c62be82010-05-06 00:08:46 +00008222 WAIT_TYPE status;
8223 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008224
Victor Stinner8c62be82010-05-06 00:08:46 +00008225 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8226 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008227
Victor Stinner8c62be82010-05-06 00:08:46 +00008228 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008229}
8230#endif /* WIFSTOPPED */
8231
8232#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008233PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008234"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008235Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008236
8237static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008238posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008239{
Victor Stinner8c62be82010-05-06 00:08:46 +00008240 WAIT_TYPE status;
8241 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008242
Victor Stinner8c62be82010-05-06 00:08:46 +00008243 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8244 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008245
Victor Stinner8c62be82010-05-06 00:08:46 +00008246 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008247}
8248#endif /* WIFSIGNALED */
8249
8250#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008251PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008252"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008253Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008254system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008255
8256static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008257posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008258{
Victor Stinner8c62be82010-05-06 00:08:46 +00008259 WAIT_TYPE status;
8260 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008261
Victor Stinner8c62be82010-05-06 00:08:46 +00008262 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8263 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008264
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008266}
8267#endif /* WIFEXITED */
8268
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008269#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008270PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008271"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008272Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008273
8274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008275posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008276{
Victor Stinner8c62be82010-05-06 00:08:46 +00008277 WAIT_TYPE status;
8278 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008279
Victor Stinner8c62be82010-05-06 00:08:46 +00008280 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8281 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008282
Victor Stinner8c62be82010-05-06 00:08:46 +00008283 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008284}
8285#endif /* WEXITSTATUS */
8286
8287#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008288PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008289"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008290Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008291value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008292
8293static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008294posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008295{
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 WAIT_TYPE status;
8297 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008298
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8300 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008301
Victor Stinner8c62be82010-05-06 00:08:46 +00008302 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008303}
8304#endif /* WTERMSIG */
8305
8306#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008307PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008308"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008309Return the signal that stopped the process that provided\n\
8310the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008311
8312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008313posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008314{
Victor Stinner8c62be82010-05-06 00:08:46 +00008315 WAIT_TYPE status;
8316 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008317
Victor Stinner8c62be82010-05-06 00:08:46 +00008318 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8319 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008320
Victor Stinner8c62be82010-05-06 00:08:46 +00008321 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008322}
8323#endif /* WSTOPSIG */
8324
8325#endif /* HAVE_SYS_WAIT_H */
8326
8327
Thomas Wouters477c8d52006-05-27 19:21:47 +00008328#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008329#ifdef _SCO_DS
8330/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8331 needed definitions in sys/statvfs.h */
8332#define _SVID3
8333#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008334#include <sys/statvfs.h>
8335
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008336static PyObject*
8337_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008338 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8339 if (v == NULL)
8340 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008341
8342#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008343 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8344 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8345 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8346 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8347 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8348 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8349 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8350 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8351 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8352 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008353#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008354 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8355 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8356 PyStructSequence_SET_ITEM(v, 2,
8357 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8358 PyStructSequence_SET_ITEM(v, 3,
8359 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8360 PyStructSequence_SET_ITEM(v, 4,
8361 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8362 PyStructSequence_SET_ITEM(v, 5,
8363 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8364 PyStructSequence_SET_ITEM(v, 6,
8365 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8366 PyStructSequence_SET_ITEM(v, 7,
8367 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8368 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8369 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008370#endif
8371
Victor Stinner8c62be82010-05-06 00:08:46 +00008372 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008373}
8374
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008375PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008376"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008377Perform an fstatvfs system call on the given fd.\n\
8378Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008379
8380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008381posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008382{
Victor Stinner8c62be82010-05-06 00:08:46 +00008383 int fd, res;
8384 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008385
Victor Stinner8c62be82010-05-06 00:08:46 +00008386 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8387 return NULL;
8388 Py_BEGIN_ALLOW_THREADS
8389 res = fstatvfs(fd, &st);
8390 Py_END_ALLOW_THREADS
8391 if (res != 0)
8392 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008393
Victor Stinner8c62be82010-05-06 00:08:46 +00008394 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008395}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008396#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008397
8398
Thomas Wouters477c8d52006-05-27 19:21:47 +00008399#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008400#include <sys/statvfs.h>
8401
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008402PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008403"statvfs(path)\n\n\
8404Perform a statvfs system call on the given path.\n\
8405\n\
8406path may always be specified as a string.\n\
8407On some platforms, path may also be specified as an open file descriptor.\n\
8408 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008409
8410static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008411posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008412{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008413 static char *keywords[] = {"path", NULL};
8414 path_t path;
8415 int result;
8416 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008417 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008418
Larry Hastings9cf065c2012-06-22 16:30:09 -07008419 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008420 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07008421#ifdef HAVE_FSTATVFS
8422 path.allow_fd = 1;
8423#endif
8424 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8425 path_converter, &path
8426 ))
8427 return NULL;
8428
8429 Py_BEGIN_ALLOW_THREADS
8430#ifdef HAVE_FSTATVFS
8431 if (path.fd != -1) {
8432#ifdef __APPLE__
8433 /* handle weak-linking on Mac OS X 10.3 */
8434 if (fstatvfs == NULL) {
8435 fd_specified("statvfs", path.fd);
8436 goto exit;
8437 }
8438#endif
8439 result = fstatvfs(path.fd, &st);
8440 }
8441 else
8442#endif
8443 result = statvfs(path.narrow, &st);
8444 Py_END_ALLOW_THREADS
8445
8446 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01008447 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008448 goto exit;
8449 }
8450
8451 return_value = _pystatvfs_fromstructstatvfs(st);
8452
8453exit:
8454 path_cleanup(&path);
8455 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008456}
8457#endif /* HAVE_STATVFS */
8458
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008459#ifdef MS_WINDOWS
8460PyDoc_STRVAR(win32__getdiskusage__doc__,
8461"_getdiskusage(path) -> (total, free)\n\n\
8462Return disk usage statistics about the given path as (total, free) tuple.");
8463
8464static PyObject *
8465win32__getdiskusage(PyObject *self, PyObject *args)
8466{
8467 BOOL retval;
8468 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008469 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008470
Victor Stinner6139c1b2011-11-09 22:14:14 +01008471 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008472 return NULL;
8473
8474 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008475 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008476 Py_END_ALLOW_THREADS
8477 if (retval == 0)
8478 return PyErr_SetFromWindowsErr(0);
8479
8480 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8481}
8482#endif
8483
8484
Fred Drakec9680921999-12-13 16:37:25 +00008485/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8486 * It maps strings representing configuration variable names to
8487 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008488 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008489 * rarely-used constants. There are three separate tables that use
8490 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008491 *
8492 * This code is always included, even if none of the interfaces that
8493 * need it are included. The #if hackery needed to avoid it would be
8494 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008495 */
8496struct constdef {
8497 char *name;
8498 long value;
8499};
8500
Fred Drake12c6e2d1999-12-14 21:25:03 +00008501static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008502conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008503 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008504{
Christian Heimes217cfd12007-12-02 14:31:20 +00008505 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008506 *valuep = PyLong_AS_LONG(arg);
8507 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008508 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008509 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008510 /* look up the value in the table using a binary search */
8511 size_t lo = 0;
8512 size_t mid;
8513 size_t hi = tablesize;
8514 int cmp;
8515 const char *confname;
8516 if (!PyUnicode_Check(arg)) {
8517 PyErr_SetString(PyExc_TypeError,
8518 "configuration names must be strings or integers");
8519 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008521 confname = _PyUnicode_AsString(arg);
8522 if (confname == NULL)
8523 return 0;
8524 while (lo < hi) {
8525 mid = (lo + hi) / 2;
8526 cmp = strcmp(confname, table[mid].name);
8527 if (cmp < 0)
8528 hi = mid;
8529 else if (cmp > 0)
8530 lo = mid + 1;
8531 else {
8532 *valuep = table[mid].value;
8533 return 1;
8534 }
8535 }
8536 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8537 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008538 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008539}
8540
8541
8542#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8543static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008544#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008545 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008546#endif
8547#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008548 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008549#endif
Fred Drakec9680921999-12-13 16:37:25 +00008550#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008551 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008552#endif
8553#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008554 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008555#endif
8556#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008557 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008558#endif
8559#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008560 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008561#endif
8562#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008563 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008564#endif
8565#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008566 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008567#endif
8568#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008569 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008570#endif
8571#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008572 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008573#endif
8574#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008575 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008576#endif
8577#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008578 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008579#endif
8580#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008581 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008582#endif
8583#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008584 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008585#endif
8586#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008587 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008588#endif
8589#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008590 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008591#endif
8592#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008593 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008594#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008595#ifdef _PC_ACL_ENABLED
8596 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8597#endif
8598#ifdef _PC_MIN_HOLE_SIZE
8599 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8600#endif
8601#ifdef _PC_ALLOC_SIZE_MIN
8602 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8603#endif
8604#ifdef _PC_REC_INCR_XFER_SIZE
8605 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8606#endif
8607#ifdef _PC_REC_MAX_XFER_SIZE
8608 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8609#endif
8610#ifdef _PC_REC_MIN_XFER_SIZE
8611 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8612#endif
8613#ifdef _PC_REC_XFER_ALIGN
8614 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8615#endif
8616#ifdef _PC_SYMLINK_MAX
8617 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8618#endif
8619#ifdef _PC_XATTR_ENABLED
8620 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8621#endif
8622#ifdef _PC_XATTR_EXISTS
8623 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8624#endif
8625#ifdef _PC_TIMESTAMP_RESOLUTION
8626 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8627#endif
Fred Drakec9680921999-12-13 16:37:25 +00008628};
8629
Fred Drakec9680921999-12-13 16:37:25 +00008630static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008631conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008632{
8633 return conv_confname(arg, valuep, posix_constants_pathconf,
8634 sizeof(posix_constants_pathconf)
8635 / sizeof(struct constdef));
8636}
8637#endif
8638
8639#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008640PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008641"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008642Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008643If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008644
8645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008646posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008647{
8648 PyObject *result = NULL;
8649 int name, fd;
8650
Fred Drake12c6e2d1999-12-14 21:25:03 +00008651 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8652 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008653 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008654
Stefan Krah0e803b32010-11-26 16:16:47 +00008655 errno = 0;
8656 limit = fpathconf(fd, name);
8657 if (limit == -1 && errno != 0)
8658 posix_error();
8659 else
8660 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008661 }
8662 return result;
8663}
8664#endif
8665
8666
8667#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008668PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008669"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008670Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008671If there is no limit, return -1.\n\
8672On some platforms, path may also be specified as an open file descriptor.\n\
8673 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00008674
8675static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008676posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00008677{
Georg Brandl306336b2012-06-24 12:55:33 +02008678 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00008679 PyObject *result = NULL;
8680 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02008681 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00008682
Georg Brandl306336b2012-06-24 12:55:33 +02008683 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008684 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02008685#ifdef HAVE_FPATHCONF
8686 path.allow_fd = 1;
8687#endif
8688 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
8689 path_converter, &path,
8690 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008691 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008692
Victor Stinner8c62be82010-05-06 00:08:46 +00008693 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02008694#ifdef HAVE_FPATHCONF
8695 if (path.fd != -1)
8696 limit = fpathconf(path.fd, name);
8697 else
8698#endif
8699 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00008700 if (limit == -1 && errno != 0) {
8701 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008702 /* could be a path or name problem */
8703 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008704 else
Victor Stinner292c8352012-10-30 02:17:38 +01008705 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 }
8707 else
8708 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008709 }
Georg Brandl306336b2012-06-24 12:55:33 +02008710 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00008711 return result;
8712}
8713#endif
8714
8715#ifdef HAVE_CONFSTR
8716static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008717#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008718 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008719#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008720#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008721 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008722#endif
8723#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008724 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008725#endif
Fred Draked86ed291999-12-15 15:34:33 +00008726#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008727 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008728#endif
8729#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008731#endif
8732#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008733 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008734#endif
8735#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008736 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008737#endif
Fred Drakec9680921999-12-13 16:37:25 +00008738#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008739 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008740#endif
8741#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008742 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008743#endif
8744#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008745 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008746#endif
8747#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008748 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008749#endif
8750#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008751 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008752#endif
8753#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008754 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008755#endif
8756#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008757 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008758#endif
8759#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008760 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008761#endif
Fred Draked86ed291999-12-15 15:34:33 +00008762#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008763 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008764#endif
Fred Drakec9680921999-12-13 16:37:25 +00008765#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008766 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008767#endif
Fred Draked86ed291999-12-15 15:34:33 +00008768#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008769 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008770#endif
8771#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008773#endif
8774#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008775 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008776#endif
8777#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008778 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008779#endif
Fred Drakec9680921999-12-13 16:37:25 +00008780#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008781 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008782#endif
8783#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008784 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008785#endif
8786#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008787 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008788#endif
8789#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008790 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008791#endif
8792#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008793 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008794#endif
8795#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008796 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008797#endif
8798#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008799 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008800#endif
8801#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008802 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008803#endif
8804#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008805 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008806#endif
8807#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008808 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008809#endif
8810#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008812#endif
8813#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008815#endif
8816#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008817 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008818#endif
8819#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008821#endif
8822#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008824#endif
8825#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008826 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008827#endif
Fred Draked86ed291999-12-15 15:34:33 +00008828#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008830#endif
8831#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008832 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008833#endif
8834#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008835 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008836#endif
8837#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008838 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008839#endif
8840#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008842#endif
8843#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008845#endif
8846#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008847 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008848#endif
8849#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008851#endif
8852#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008853 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008854#endif
8855#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008857#endif
8858#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008860#endif
8861#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008863#endif
8864#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008866#endif
Fred Drakec9680921999-12-13 16:37:25 +00008867};
8868
8869static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008870conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008871{
8872 return conv_confname(arg, valuep, posix_constants_confstr,
8873 sizeof(posix_constants_confstr)
8874 / sizeof(struct constdef));
8875}
8876
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008877PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008878"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008879Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008880
8881static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008882posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008883{
8884 PyObject *result = NULL;
8885 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008886 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008887 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008888
Victor Stinnercb043522010-09-10 23:49:04 +00008889 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8890 return NULL;
8891
8892 errno = 0;
8893 len = confstr(name, buffer, sizeof(buffer));
8894 if (len == 0) {
8895 if (errno) {
8896 posix_error();
8897 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008898 }
8899 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008900 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008901 }
8902 }
Victor Stinnercb043522010-09-10 23:49:04 +00008903
8904 if ((unsigned int)len >= sizeof(buffer)) {
8905 char *buf = PyMem_Malloc(len);
8906 if (buf == NULL)
8907 return PyErr_NoMemory();
8908 confstr(name, buf, len);
8909 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8910 PyMem_Free(buf);
8911 }
8912 else
8913 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008914 return result;
8915}
8916#endif
8917
8918
8919#ifdef HAVE_SYSCONF
8920static struct constdef posix_constants_sysconf[] = {
8921#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008922 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008923#endif
8924#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008925 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008926#endif
8927#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008929#endif
8930#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008931 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008932#endif
8933#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008935#endif
8936#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008938#endif
8939#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008941#endif
8942#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008944#endif
8945#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008946 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008947#endif
8948#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008949 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008950#endif
Fred Draked86ed291999-12-15 15:34:33 +00008951#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008952 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008953#endif
8954#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008955 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008956#endif
Fred Drakec9680921999-12-13 16:37:25 +00008957#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008959#endif
Fred Drakec9680921999-12-13 16:37:25 +00008960#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008962#endif
8963#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008965#endif
8966#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008967 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008968#endif
8969#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008970 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008971#endif
8972#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008973 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008974#endif
Fred Draked86ed291999-12-15 15:34:33 +00008975#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008977#endif
Fred Drakec9680921999-12-13 16:37:25 +00008978#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008980#endif
8981#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008982 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008983#endif
8984#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008985 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008986#endif
8987#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008988 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008989#endif
8990#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008992#endif
Fred Draked86ed291999-12-15 15:34:33 +00008993#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008994 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008995#endif
Fred Drakec9680921999-12-13 16:37:25 +00008996#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008997 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008998#endif
8999#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009000 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009001#endif
9002#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009003 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009004#endif
9005#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009007#endif
9008#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009009 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009010#endif
9011#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009012 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009013#endif
9014#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009015 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009016#endif
9017#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009018 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009019#endif
9020#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009021 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009022#endif
9023#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009024 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009025#endif
9026#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009028#endif
9029#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009031#endif
9032#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009033 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009034#endif
9035#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009037#endif
9038#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009039 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009040#endif
9041#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009043#endif
9044#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009046#endif
9047#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009048 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009049#endif
9050#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009052#endif
9053#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009055#endif
9056#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009058#endif
9059#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009060 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009061#endif
9062#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009063 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009064#endif
Fred Draked86ed291999-12-15 15:34:33 +00009065#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009067#endif
Fred Drakec9680921999-12-13 16:37:25 +00009068#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009070#endif
9071#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009072 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009073#endif
9074#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009075 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009076#endif
Fred Draked86ed291999-12-15 15:34:33 +00009077#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009078 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009079#endif
Fred Drakec9680921999-12-13 16:37:25 +00009080#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009082#endif
Fred Draked86ed291999-12-15 15:34:33 +00009083#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009085#endif
9086#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009088#endif
Fred Drakec9680921999-12-13 16:37:25 +00009089#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009091#endif
9092#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009093 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009094#endif
9095#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009096 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009097#endif
9098#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009099 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009100#endif
Fred Draked86ed291999-12-15 15:34:33 +00009101#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009103#endif
Fred Drakec9680921999-12-13 16:37:25 +00009104#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009106#endif
9107#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009109#endif
9110#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009112#endif
9113#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009115#endif
9116#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009117 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009118#endif
9119#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009121#endif
9122#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009124#endif
Fred Draked86ed291999-12-15 15:34:33 +00009125#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009127#endif
Fred Drakec9680921999-12-13 16:37:25 +00009128#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009129 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009130#endif
9131#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009132 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009133#endif
Fred Draked86ed291999-12-15 15:34:33 +00009134#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009135 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009136#endif
Fred Drakec9680921999-12-13 16:37:25 +00009137#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009139#endif
9140#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009142#endif
9143#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009145#endif
9146#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009147 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009148#endif
9149#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009150 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009151#endif
9152#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009153 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009154#endif
9155#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009156 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009157#endif
9158#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009159 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009160#endif
9161#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009162 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009163#endif
Fred Draked86ed291999-12-15 15:34:33 +00009164#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009165 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009166#endif
9167#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009168 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009169#endif
Fred Drakec9680921999-12-13 16:37:25 +00009170#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009172#endif
9173#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009174 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009175#endif
9176#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009178#endif
9179#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009181#endif
9182#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009184#endif
9185#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009186 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009187#endif
9188#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009189 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009190#endif
9191#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009193#endif
9194#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009196#endif
9197#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009199#endif
9200#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009202#endif
9203#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009205#endif
9206#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009207 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009208#endif
9209#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009210 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009211#endif
9212#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009213 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009214#endif
9215#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009216 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009217#endif
9218#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009219 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009220#endif
9221#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009222 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009223#endif
9224#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009225 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009226#endif
9227#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009228 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009229#endif
9230#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009231 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009232#endif
9233#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009234 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009235#endif
9236#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009237 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009238#endif
9239#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009240 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009241#endif
9242#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009243 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009244#endif
9245#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009246 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009247#endif
9248#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009249 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009250#endif
9251#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009252 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009253#endif
9254#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009255 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009256#endif
9257#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009258 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009259#endif
9260#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009261 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009262#endif
9263#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009264 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009265#endif
9266#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009267 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009268#endif
9269#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009270 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009271#endif
9272#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009273 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009274#endif
Fred Draked86ed291999-12-15 15:34:33 +00009275#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009276 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009277#endif
Fred Drakec9680921999-12-13 16:37:25 +00009278#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009279 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009280#endif
9281#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009282 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009283#endif
9284#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009286#endif
9287#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009288 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009289#endif
9290#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009291 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009292#endif
9293#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009294 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009295#endif
9296#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009298#endif
9299#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009300 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009301#endif
9302#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009303 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009304#endif
9305#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009306 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009307#endif
9308#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009309 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009310#endif
9311#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009313#endif
9314#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009315 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009316#endif
9317#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009318 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009319#endif
9320#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009321 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009322#endif
9323#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009324 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009325#endif
9326#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009328#endif
9329#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009330 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009331#endif
9332#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009333 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009334#endif
9335#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009336 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009337#endif
9338#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009340#endif
9341#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009342 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009343#endif
9344#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009345 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009346#endif
9347#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009348 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009349#endif
9350#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009351 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009352#endif
9353#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009354 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009355#endif
9356#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009358#endif
9359#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009361#endif
9362#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009363 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009364#endif
9365#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009366 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009367#endif
9368#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009369 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009370#endif
9371#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009372 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009373#endif
9374#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009375 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009376#endif
9377#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009378 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009379#endif
9380#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009382#endif
9383#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009385#endif
9386#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009388#endif
9389#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009391#endif
9392#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009394#endif
9395#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009397#endif
9398#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009400#endif
9401#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009403#endif
9404#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009406#endif
9407#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009409#endif
9410#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009411 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009412#endif
9413};
9414
9415static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009416conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009417{
9418 return conv_confname(arg, valuep, posix_constants_sysconf,
9419 sizeof(posix_constants_sysconf)
9420 / sizeof(struct constdef));
9421}
9422
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009423PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009424"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009425Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009426
9427static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009428posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009429{
9430 PyObject *result = NULL;
9431 int name;
9432
9433 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9434 int value;
9435
9436 errno = 0;
9437 value = sysconf(name);
9438 if (value == -1 && errno != 0)
9439 posix_error();
9440 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009441 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009442 }
9443 return result;
9444}
9445#endif
9446
9447
Fred Drakebec628d1999-12-15 18:31:10 +00009448/* This code is used to ensure that the tables of configuration value names
9449 * are in sorted order as required by conv_confname(), and also to build the
9450 * the exported dictionaries that are used to publish information about the
9451 * names available on the host platform.
9452 *
9453 * Sorting the table at runtime ensures that the table is properly ordered
9454 * when used, even for platforms we're not able to test on. It also makes
9455 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009456 */
Fred Drakebec628d1999-12-15 18:31:10 +00009457
9458static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009459cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009460{
9461 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009463 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009464 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009465
9466 return strcmp(c1->name, c2->name);
9467}
9468
9469static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009470setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009471 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009472{
Fred Drakebec628d1999-12-15 18:31:10 +00009473 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009474 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009475
9476 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9477 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009478 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009479 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009480
Barry Warsaw3155db32000-04-13 15:20:40 +00009481 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009482 PyObject *o = PyLong_FromLong(table[i].value);
9483 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9484 Py_XDECREF(o);
9485 Py_DECREF(d);
9486 return -1;
9487 }
9488 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009489 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009490 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009491}
9492
Fred Drakebec628d1999-12-15 18:31:10 +00009493/* Return -1 on failure, 0 on success. */
9494static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009495setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009496{
9497#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009498 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009499 sizeof(posix_constants_pathconf)
9500 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009501 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009502 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009503#endif
9504#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009505 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009506 sizeof(posix_constants_confstr)
9507 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009508 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009509 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009510#endif
9511#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009512 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009513 sizeof(posix_constants_sysconf)
9514 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009515 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009516 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009517#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009518 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009519}
Fred Draked86ed291999-12-15 15:34:33 +00009520
9521
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009522PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009523"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009524Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009525in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009526
9527static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009528posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009529{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009530 abort();
9531 /*NOTREACHED*/
9532 Py_FatalError("abort() called from Python code didn't abort!");
9533 return NULL;
9534}
Fred Drakebec628d1999-12-15 18:31:10 +00009535
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009536#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009537PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009538"startfile(filepath [, operation]) - Start a file with its associated\n\
9539application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009540\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009541When \"operation\" is not specified or \"open\", this acts like\n\
9542double-clicking the file in Explorer, or giving the file name as an\n\
9543argument to the DOS \"start\" command: the file is opened with whatever\n\
9544application (if any) its extension is associated.\n\
9545When another \"operation\" is given, it specifies what should be done with\n\
9546the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009547\n\
9548startfile returns as soon as the associated application is launched.\n\
9549There is no option to wait for the application to close, and no way\n\
9550to retrieve the application's exit status.\n\
9551\n\
9552The filepath is relative to the current directory. If you want to use\n\
9553an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009554the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009555
9556static PyObject *
9557win32_startfile(PyObject *self, PyObject *args)
9558{
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 PyObject *ofilepath;
9560 char *filepath;
9561 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009562 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009564
Victor Stinnereb5657a2011-09-30 01:44:27 +02009565 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 if (!PyArg_ParseTuple(args, "U|s:startfile",
9567 &unipath, &operation)) {
9568 PyErr_Clear();
9569 goto normal;
9570 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009571
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009573 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009575 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 PyErr_Clear();
9577 operation = NULL;
9578 goto normal;
9579 }
9580 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009581
Victor Stinnereb5657a2011-09-30 01:44:27 +02009582 wpath = PyUnicode_AsUnicode(unipath);
9583 if (wpath == NULL)
9584 goto normal;
9585 if (uoperation) {
9586 woperation = PyUnicode_AsUnicode(uoperation);
9587 if (woperation == NULL)
9588 goto normal;
9589 }
9590 else
9591 woperation = NULL;
9592
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009594 rc = ShellExecuteW((HWND)0, woperation, wpath,
9595 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 Py_END_ALLOW_THREADS
9597
Victor Stinnereb5657a2011-09-30 01:44:27 +02009598 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009600 win32_error_object("startfile", unipath);
9601 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 }
9603 Py_INCREF(Py_None);
9604 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009605
9606normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9608 PyUnicode_FSConverter, &ofilepath,
9609 &operation))
9610 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009611 if (win32_warn_bytes_api()) {
9612 Py_DECREF(ofilepath);
9613 return NULL;
9614 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 filepath = PyBytes_AsString(ofilepath);
9616 Py_BEGIN_ALLOW_THREADS
9617 rc = ShellExecute((HWND)0, operation, filepath,
9618 NULL, NULL, SW_SHOWNORMAL);
9619 Py_END_ALLOW_THREADS
9620 if (rc <= (HINSTANCE)32) {
9621 PyObject *errval = win32_error("startfile", filepath);
9622 Py_DECREF(ofilepath);
9623 return errval;
9624 }
9625 Py_DECREF(ofilepath);
9626 Py_INCREF(Py_None);
9627 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009628}
9629#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009630
Martin v. Löwis438b5342002-12-27 10:16:42 +00009631#ifdef HAVE_GETLOADAVG
9632PyDoc_STRVAR(posix_getloadavg__doc__,
9633"getloadavg() -> (float, float, float)\n\n\
9634Return the number of processes in the system run queue averaged over\n\
9635the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9636was unobtainable");
9637
9638static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009639posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009640{
9641 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009642 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009643 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9644 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009645 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009646 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009647}
9648#endif
9649
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009650PyDoc_STRVAR(device_encoding__doc__,
9651"device_encoding(fd) -> str\n\n\
9652Return a string describing the encoding of the device\n\
9653if the output is a terminal; else return None.");
9654
9655static PyObject *
9656device_encoding(PyObject *self, PyObject *args)
9657{
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009659
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9661 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009662
9663 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009664}
9665
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009666#ifdef HAVE_SETRESUID
9667PyDoc_STRVAR(posix_setresuid__doc__,
9668"setresuid(ruid, euid, suid)\n\n\
9669Set the current process's real, effective, and saved user ids.");
9670
9671static PyObject*
9672posix_setresuid (PyObject *self, PyObject *args)
9673{
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 /* We assume uid_t is no larger than a long. */
9675 long ruid, euid, suid;
9676 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9677 return NULL;
9678 if (setresuid(ruid, euid, suid) < 0)
9679 return posix_error();
9680 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009681}
9682#endif
9683
9684#ifdef HAVE_SETRESGID
9685PyDoc_STRVAR(posix_setresgid__doc__,
9686"setresgid(rgid, egid, sgid)\n\n\
9687Set the current process's real, effective, and saved group ids.");
9688
9689static PyObject*
9690posix_setresgid (PyObject *self, PyObject *args)
9691{
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 /* We assume uid_t is no larger than a long. */
9693 long rgid, egid, sgid;
9694 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9695 return NULL;
9696 if (setresgid(rgid, egid, sgid) < 0)
9697 return posix_error();
9698 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009699}
9700#endif
9701
9702#ifdef HAVE_GETRESUID
9703PyDoc_STRVAR(posix_getresuid__doc__,
9704"getresuid() -> (ruid, euid, suid)\n\n\
9705Get tuple of the current process's real, effective, and saved user ids.");
9706
9707static PyObject*
9708posix_getresuid (PyObject *self, PyObject *noargs)
9709{
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 uid_t ruid, euid, suid;
9711 long l_ruid, l_euid, l_suid;
9712 if (getresuid(&ruid, &euid, &suid) < 0)
9713 return posix_error();
9714 /* Force the values into long's as we don't know the size of uid_t. */
9715 l_ruid = ruid;
9716 l_euid = euid;
9717 l_suid = suid;
9718 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009719}
9720#endif
9721
9722#ifdef HAVE_GETRESGID
9723PyDoc_STRVAR(posix_getresgid__doc__,
9724"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009725Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009726
9727static PyObject*
9728posix_getresgid (PyObject *self, PyObject *noargs)
9729{
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 uid_t rgid, egid, sgid;
9731 long l_rgid, l_egid, l_sgid;
9732 if (getresgid(&rgid, &egid, &sgid) < 0)
9733 return posix_error();
9734 /* Force the values into long's as we don't know the size of uid_t. */
9735 l_rgid = rgid;
9736 l_egid = egid;
9737 l_sgid = sgid;
9738 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009739}
9740#endif
9741
Benjamin Peterson9428d532011-09-14 11:45:52 -04009742#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -04009743
Benjamin Peterson799bd802011-08-31 22:15:17 -04009744PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009745"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
9746Return the value of extended attribute attribute on path.\n\
9747\n\
9748path may be either a string or an open file descriptor.\n\
9749If follow_symlinks is False, and the last element of the path is a symbolic\n\
9750 link, getxattr will examine the symbolic link itself instead of the file\n\
9751 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009752
9753static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009754posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009755{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009756 path_t path;
9757 path_t attribute;
9758 int follow_symlinks = 1;
9759 PyObject *buffer = NULL;
9760 int i;
9761 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009762
Larry Hastings9cf065c2012-06-22 16:30:09 -07009763 memset(&path, 0, sizeof(path));
9764 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009765 path.function_name = "getxattr";
9766 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009767 path.allow_fd = 1;
9768 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
9769 path_converter, &path,
9770 path_converter, &attribute,
9771 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009772 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009773
Larry Hastings9cf065c2012-06-22 16:30:09 -07009774 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
9775 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009776
Larry Hastings9cf065c2012-06-22 16:30:09 -07009777 for (i = 0; ; i++) {
9778 void *ptr;
9779 ssize_t result;
9780 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
9781 Py_ssize_t buffer_size = buffer_sizes[i];
9782 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +01009783 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009784 goto exit;
9785 }
9786 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
9787 if (!buffer)
9788 goto exit;
9789 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009790
Larry Hastings9cf065c2012-06-22 16:30:09 -07009791 Py_BEGIN_ALLOW_THREADS;
9792 if (path.fd >= 0)
9793 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
9794 else if (follow_symlinks)
9795 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9796 else
9797 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9798 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009799
Larry Hastings9cf065c2012-06-22 16:30:09 -07009800 if (result < 0) {
9801 Py_DECREF(buffer);
9802 buffer = NULL;
9803 if (errno == ERANGE)
9804 continue;
Victor Stinner292c8352012-10-30 02:17:38 +01009805 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009806 goto exit;
9807 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009808
Larry Hastings9cf065c2012-06-22 16:30:09 -07009809 if (result != buffer_size) {
9810 /* Can only shrink. */
9811 _PyBytes_Resize(&buffer, result);
9812 }
9813 break;
9814 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009815
Larry Hastings9cf065c2012-06-22 16:30:09 -07009816exit:
9817 path_cleanup(&path);
9818 path_cleanup(&attribute);
9819 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009820}
9821
9822PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009823"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
9824Set extended attribute attribute on path to value.\n\
9825path may be either a string or an open file descriptor.\n\
9826If follow_symlinks is False, and the last element of the path is a symbolic\n\
9827 link, setxattr will modify the symbolic link itself instead of the file\n\
9828 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009829
9830static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009831posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009832{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009833 path_t path;
9834 path_t attribute;
9835 Py_buffer value;
9836 int flags = 0;
9837 int follow_symlinks = 1;
9838 int result;
9839 PyObject *return_value = NULL;
9840 static char *keywords[] = {"path", "attribute", "value",
9841 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009842
Larry Hastings9cf065c2012-06-22 16:30:09 -07009843 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009844 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009845 path.allow_fd = 1;
9846 memset(&attribute, 0, sizeof(attribute));
9847 memset(&value, 0, sizeof(value));
9848 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
9849 keywords,
9850 path_converter, &path,
9851 path_converter, &attribute,
9852 &value, &flags,
9853 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009854 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009855
9856 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
9857 goto exit;
9858
Benjamin Peterson799bd802011-08-31 22:15:17 -04009859 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009860 if (path.fd > -1)
9861 result = fsetxattr(path.fd, attribute.narrow,
9862 value.buf, value.len, flags);
9863 else if (follow_symlinks)
9864 result = setxattr(path.narrow, attribute.narrow,
9865 value.buf, value.len, flags);
9866 else
9867 result = lsetxattr(path.narrow, attribute.narrow,
9868 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009869 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009870
Larry Hastings9cf065c2012-06-22 16:30:09 -07009871 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009872 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009873 goto exit;
9874 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009875
Larry Hastings9cf065c2012-06-22 16:30:09 -07009876 return_value = Py_None;
9877 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009878
Larry Hastings9cf065c2012-06-22 16:30:09 -07009879exit:
9880 path_cleanup(&path);
9881 path_cleanup(&attribute);
9882 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009883
Larry Hastings9cf065c2012-06-22 16:30:09 -07009884 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009885}
9886
9887PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009888"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
9889Remove extended attribute attribute on path.\n\
9890path may be either a string or an open file descriptor.\n\
9891If follow_symlinks is False, and the last element of the path is a symbolic\n\
9892 link, removexattr will modify the symbolic link itself instead of the file\n\
9893 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009894
9895static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009896posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009897{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009898 path_t path;
9899 path_t attribute;
9900 int follow_symlinks = 1;
9901 int result;
9902 PyObject *return_value = NULL;
9903 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009904
Larry Hastings9cf065c2012-06-22 16:30:09 -07009905 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009906 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009907 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009908 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009909 path.allow_fd = 1;
9910 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
9911 keywords,
9912 path_converter, &path,
9913 path_converter, &attribute,
9914 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009915 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009916
9917 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
9918 goto exit;
9919
Benjamin Peterson799bd802011-08-31 22:15:17 -04009920 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009921 if (path.fd > -1)
9922 result = fremovexattr(path.fd, attribute.narrow);
9923 else if (follow_symlinks)
9924 result = removexattr(path.narrow, attribute.narrow);
9925 else
9926 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009927 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009928
Larry Hastings9cf065c2012-06-22 16:30:09 -07009929 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009930 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009931 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009932 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009933
Larry Hastings9cf065c2012-06-22 16:30:09 -07009934 return_value = Py_None;
9935 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009936
Larry Hastings9cf065c2012-06-22 16:30:09 -07009937exit:
9938 path_cleanup(&path);
9939 path_cleanup(&attribute);
9940
9941 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009942}
9943
9944PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009945"listxattr(path='.', *, follow_symlinks=True)\n\n\
9946Return a list of extended attributes on path.\n\
9947\n\
9948path may be either None, a string, or an open file descriptor.\n\
9949if path is None, listxattr will examine the current directory.\n\
9950If follow_symlinks is False, and the last element of the path is a symbolic\n\
9951 link, listxattr will examine the symbolic link itself instead of the file\n\
9952 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009953
9954static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009955posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009956{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009957 path_t path;
9958 int follow_symlinks = 1;
9959 Py_ssize_t i;
9960 PyObject *result = NULL;
9961 char *buffer = NULL;
9962 char *name;
9963 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009964
Larry Hastings9cf065c2012-06-22 16:30:09 -07009965 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009966 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009967 path.allow_fd = 1;
9968 path.fd = -1;
9969 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
9970 path_converter, &path,
9971 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009972 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009973
Larry Hastings9cf065c2012-06-22 16:30:09 -07009974 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
9975 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009976
Larry Hastings9cf065c2012-06-22 16:30:09 -07009977 name = path.narrow ? path.narrow : ".";
9978 for (i = 0; ; i++) {
9979 char *start, *trace, *end;
9980 ssize_t length;
9981 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
9982 Py_ssize_t buffer_size = buffer_sizes[i];
9983 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +02009984 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +01009985 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009986 break;
9987 }
9988 buffer = PyMem_MALLOC(buffer_size);
9989 if (!buffer) {
9990 PyErr_NoMemory();
9991 break;
9992 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009993
Larry Hastings9cf065c2012-06-22 16:30:09 -07009994 Py_BEGIN_ALLOW_THREADS;
9995 if (path.fd > -1)
9996 length = flistxattr(path.fd, buffer, buffer_size);
9997 else if (follow_symlinks)
9998 length = listxattr(name, buffer, buffer_size);
9999 else
10000 length = llistxattr(name, buffer, buffer_size);
10001 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010002
Larry Hastings9cf065c2012-06-22 16:30:09 -070010003 if (length < 0) {
10004 if (errno == ERANGE)
10005 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010006 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010007 break;
10008 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010009
Larry Hastings9cf065c2012-06-22 16:30:09 -070010010 result = PyList_New(0);
10011 if (!result) {
10012 goto exit;
10013 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010014
Larry Hastings9cf065c2012-06-22 16:30:09 -070010015 end = buffer + length;
10016 for (trace = start = buffer; trace != end; trace++) {
10017 if (!*trace) {
10018 int error;
10019 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10020 trace - start);
10021 if (!attribute) {
10022 Py_DECREF(result);
10023 result = NULL;
10024 goto exit;
10025 }
10026 error = PyList_Append(result, attribute);
10027 Py_DECREF(attribute);
10028 if (error) {
10029 Py_DECREF(result);
10030 result = NULL;
10031 goto exit;
10032 }
10033 start = trace + 1;
10034 }
10035 }
10036 break;
10037 }
10038exit:
10039 path_cleanup(&path);
10040 if (buffer)
10041 PyMem_FREE(buffer);
10042 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010043}
10044
Benjamin Peterson9428d532011-09-14 11:45:52 -040010045#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010046
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010047
Georg Brandl2fb477c2012-02-21 00:33:36 +010010048PyDoc_STRVAR(posix_urandom__doc__,
10049"urandom(n) -> str\n\n\
10050Return n random bytes suitable for cryptographic use.");
10051
10052static PyObject *
10053posix_urandom(PyObject *self, PyObject *args)
10054{
10055 Py_ssize_t size;
10056 PyObject *result;
10057 int ret;
10058
10059 /* Read arguments */
10060 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10061 return NULL;
10062 if (size < 0)
10063 return PyErr_Format(PyExc_ValueError,
10064 "negative argument not allowed");
10065 result = PyBytes_FromStringAndSize(NULL, size);
10066 if (result == NULL)
10067 return NULL;
10068
10069 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10070 PyBytes_GET_SIZE(result));
10071 if (ret == -1) {
10072 Py_DECREF(result);
10073 return NULL;
10074 }
10075 return result;
10076}
10077
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010078/* Terminal size querying */
10079
10080static PyTypeObject TerminalSizeType;
10081
10082PyDoc_STRVAR(TerminalSize_docstring,
10083 "A tuple of (columns, lines) for holding terminal window size");
10084
10085static PyStructSequence_Field TerminalSize_fields[] = {
10086 {"columns", "width of the terminal window in characters"},
10087 {"lines", "height of the terminal window in characters"},
10088 {NULL, NULL}
10089};
10090
10091static PyStructSequence_Desc TerminalSize_desc = {
10092 "os.terminal_size",
10093 TerminalSize_docstring,
10094 TerminalSize_fields,
10095 2,
10096};
10097
10098#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10099PyDoc_STRVAR(termsize__doc__,
10100 "Return the size of the terminal window as (columns, lines).\n" \
10101 "\n" \
10102 "The optional argument fd (default standard output) specifies\n" \
10103 "which file descriptor should be queried.\n" \
10104 "\n" \
10105 "If the file descriptor is not connected to a terminal, an OSError\n" \
10106 "is thrown.\n" \
10107 "\n" \
10108 "This function will only be defined if an implementation is\n" \
10109 "available for this system.\n" \
10110 "\n" \
10111 "shutil.get_terminal_size is the high-level function which should \n" \
10112 "normally be used, os.get_terminal_size is the low-level implementation.");
10113
10114static PyObject*
10115get_terminal_size(PyObject *self, PyObject *args)
10116{
10117 int columns, lines;
10118 PyObject *termsize;
10119
10120 int fd = fileno(stdout);
10121 /* Under some conditions stdout may not be connected and
10122 * fileno(stdout) may point to an invalid file descriptor. For example
10123 * GUI apps don't have valid standard streams by default.
10124 *
10125 * If this happens, and the optional fd argument is not present,
10126 * the ioctl below will fail returning EBADF. This is what we want.
10127 */
10128
10129 if (!PyArg_ParseTuple(args, "|i", &fd))
10130 return NULL;
10131
10132#ifdef TERMSIZE_USE_IOCTL
10133 {
10134 struct winsize w;
10135 if (ioctl(fd, TIOCGWINSZ, &w))
10136 return PyErr_SetFromErrno(PyExc_OSError);
10137 columns = w.ws_col;
10138 lines = w.ws_row;
10139 }
10140#endif /* TERMSIZE_USE_IOCTL */
10141
10142#ifdef TERMSIZE_USE_CONIO
10143 {
10144 DWORD nhandle;
10145 HANDLE handle;
10146 CONSOLE_SCREEN_BUFFER_INFO csbi;
10147 switch (fd) {
10148 case 0: nhandle = STD_INPUT_HANDLE;
10149 break;
10150 case 1: nhandle = STD_OUTPUT_HANDLE;
10151 break;
10152 case 2: nhandle = STD_ERROR_HANDLE;
10153 break;
10154 default:
10155 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10156 }
10157 handle = GetStdHandle(nhandle);
10158 if (handle == NULL)
10159 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10160 if (handle == INVALID_HANDLE_VALUE)
10161 return PyErr_SetFromWindowsErr(0);
10162
10163 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10164 return PyErr_SetFromWindowsErr(0);
10165
10166 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10167 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10168 }
10169#endif /* TERMSIZE_USE_CONIO */
10170
10171 termsize = PyStructSequence_New(&TerminalSizeType);
10172 if (termsize == NULL)
10173 return NULL;
10174 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10175 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10176 if (PyErr_Occurred()) {
10177 Py_DECREF(termsize);
10178 return NULL;
10179 }
10180 return termsize;
10181}
10182#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10183
10184
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010185static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010186 {"access", (PyCFunction)posix_access,
10187 METH_VARARGS | METH_KEYWORDS,
10188 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010189#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010191#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010192 {"chdir", (PyCFunction)posix_chdir,
10193 METH_VARARGS | METH_KEYWORDS,
10194 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010195#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010196 {"chflags", (PyCFunction)posix_chflags,
10197 METH_VARARGS | METH_KEYWORDS,
10198 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010199#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010200 {"chmod", (PyCFunction)posix_chmod,
10201 METH_VARARGS | METH_KEYWORDS,
10202 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010203#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010205#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010206#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010207 {"chown", (PyCFunction)posix_chown,
10208 METH_VARARGS | METH_KEYWORDS,
10209 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010210#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010211#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010213#endif /* HAVE_LCHMOD */
10214#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010216#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010217#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010219#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010220#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010222#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010223#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010225#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010226#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010228#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010229#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10231 METH_NOARGS, posix_getcwd__doc__},
10232 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10233 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010234#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010235#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10236 {"link", (PyCFunction)posix_link,
10237 METH_VARARGS | METH_KEYWORDS,
10238 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010239#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010240 {"listdir", (PyCFunction)posix_listdir,
10241 METH_VARARGS | METH_KEYWORDS,
10242 posix_listdir__doc__},
10243 {"lstat", (PyCFunction)posix_lstat,
10244 METH_VARARGS | METH_KEYWORDS,
10245 posix_lstat__doc__},
10246 {"mkdir", (PyCFunction)posix_mkdir,
10247 METH_VARARGS | METH_KEYWORDS,
10248 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010249#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010251#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010252#ifdef HAVE_GETPRIORITY
10253 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10254#endif /* HAVE_GETPRIORITY */
10255#ifdef HAVE_SETPRIORITY
10256 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10257#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010258#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010259 {"readlink", (PyCFunction)posix_readlink,
10260 METH_VARARGS | METH_KEYWORDS,
10261 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010262#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010263#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010264 {"readlink", (PyCFunction)win_readlink,
10265 METH_VARARGS | METH_KEYWORDS,
10266 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010267#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010268 {"rename", (PyCFunction)posix_rename,
10269 METH_VARARGS | METH_KEYWORDS,
10270 posix_rename__doc__},
10271 {"replace", (PyCFunction)posix_replace,
10272 METH_VARARGS | METH_KEYWORDS,
10273 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010274 {"rmdir", (PyCFunction)posix_rmdir,
10275 METH_VARARGS | METH_KEYWORDS,
10276 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010277 {"stat", (PyCFunction)posix_stat,
10278 METH_VARARGS | METH_KEYWORDS,
10279 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010281#if defined(HAVE_SYMLINK)
10282 {"symlink", (PyCFunction)posix_symlink,
10283 METH_VARARGS | METH_KEYWORDS,
10284 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010285#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010286#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010288#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010290#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010292#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010293 {"unlink", (PyCFunction)posix_unlink,
10294 METH_VARARGS | METH_KEYWORDS,
10295 posix_unlink__doc__},
10296 {"remove", (PyCFunction)posix_unlink,
10297 METH_VARARGS | METH_KEYWORDS,
10298 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010299 {"utime", (PyCFunction)posix_utime,
10300 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010301#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010303#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010305#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010307 {"execve", (PyCFunction)posix_execve,
10308 METH_VARARGS | METH_KEYWORDS,
10309 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010310#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010311#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10313 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000010314#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010315#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010317#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010318#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010320#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010321#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010322#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010323 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10324 {"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 +020010325#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010326#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010327 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010328#endif
10329#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010330 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010331#endif
10332#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010333 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010334#endif
10335#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010336 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010337#endif
10338#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010339 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010340#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010341 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010342#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010343 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10344 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10345#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010346#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010347#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010349#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010350#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010352#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010353#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010355#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010356#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010358#endif /* HAVE_GETEUID */
10359#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010361#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010362#ifdef HAVE_GETGROUPLIST
10363 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10364#endif
Fred Drakec9680921999-12-13 16:37:25 +000010365#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010367#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010369#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010371#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010372#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010374#endif /* HAVE_GETPPID */
10375#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010377#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010378#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010380#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010381#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010383#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010384#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010386#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010387#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010389#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010390#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10392 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010393#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010394#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010396#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010397#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010399#endif /* HAVE_SETEUID */
10400#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010402#endif /* HAVE_SETEGID */
10403#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010405#endif /* HAVE_SETREUID */
10406#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010408#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010409#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010411#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010412#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010414#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010415#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010417#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010418#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010420#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010421#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010423#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010424#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010425 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010426#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010427#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010428 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010429#endif /* HAVE_WAIT3 */
10430#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010431 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010432#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010433#if defined(HAVE_WAITID) && !defined(__APPLE__)
10434 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10435#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010436#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010438#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010439#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010441#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010442#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010443 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010444#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010445#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010447#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010448#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010450#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010451#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010452 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010453#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010454 {"open", (PyCFunction)posix_open,\
10455 METH_VARARGS | METH_KEYWORDS,
10456 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10458 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10459 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10460 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10461 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010462#ifdef HAVE_LOCKF
10463 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10464#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10466 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010467#ifdef HAVE_READV
10468 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10469#endif
10470#ifdef HAVE_PREAD
10471 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10472#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010474#ifdef HAVE_WRITEV
10475 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10476#endif
10477#ifdef HAVE_PWRITE
10478 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10479#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010480#ifdef HAVE_SENDFILE
10481 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10482 posix_sendfile__doc__},
10483#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010484 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010486#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010488#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010489#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010490 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010491#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010492#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070010493 {"mkfifo", (PyCFunction)posix_mkfifo,
10494 METH_VARARGS | METH_KEYWORDS,
10495 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010496#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010497#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010498 {"mknod", (PyCFunction)posix_mknod,
10499 METH_VARARGS | METH_KEYWORDS,
10500 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010501#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010502#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10504 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10505 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010506#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010507#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010508 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010509#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010510#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020010511 {"truncate", (PyCFunction)posix_truncate,
10512 METH_VARARGS | METH_KEYWORDS,
10513 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010514#endif
10515#ifdef HAVE_POSIX_FALLOCATE
10516 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10517#endif
10518#ifdef HAVE_POSIX_FADVISE
10519 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10520#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010521#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010523#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010524#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010526#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010527 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010528#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010529 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010530#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010531#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010532 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010533#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010534#ifdef HAVE_SYNC
10535 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10536#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010537#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010539#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010540#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010541#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010543#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010544#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010546#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010547#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010549#endif /* WIFSTOPPED */
10550#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010552#endif /* WIFSIGNALED */
10553#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010555#endif /* WIFEXITED */
10556#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010558#endif /* WEXITSTATUS */
10559#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010561#endif /* WTERMSIG */
10562#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010564#endif /* WSTOPSIG */
10565#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010566#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010567 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010568#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010569#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010570 {"statvfs", (PyCFunction)posix_statvfs,
10571 METH_VARARGS | METH_KEYWORDS,
10572 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010573#endif
Fred Drakec9680921999-12-13 16:37:25 +000010574#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010576#endif
10577#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010579#endif
10580#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010582#endif
10583#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020010584 {"pathconf", (PyCFunction)posix_pathconf,
10585 METH_VARARGS | METH_KEYWORDS,
10586 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010587#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010589#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010590 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010591 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010592 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010593 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010594#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010595#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010597#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010598 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010599#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010601#endif
10602#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010604#endif
10605#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010606 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010607#endif
10608#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010609 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010610#endif
10611
Benjamin Peterson9428d532011-09-14 11:45:52 -040010612#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010613 {"setxattr", (PyCFunction)posix_setxattr,
10614 METH_VARARGS | METH_KEYWORDS,
10615 posix_setxattr__doc__},
10616 {"getxattr", (PyCFunction)posix_getxattr,
10617 METH_VARARGS | METH_KEYWORDS,
10618 posix_getxattr__doc__},
10619 {"removexattr", (PyCFunction)posix_removexattr,
10620 METH_VARARGS | METH_KEYWORDS,
10621 posix_removexattr__doc__},
10622 {"listxattr", (PyCFunction)posix_listxattr,
10623 METH_VARARGS | METH_KEYWORDS,
10624 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040010625#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010626#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10627 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
10628#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010629 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010630};
10631
10632
Barry Warsaw4a342091996-12-19 23:50:02 +000010633static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010634ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010635{
Victor Stinner8c62be82010-05-06 00:08:46 +000010636 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010637}
10638
Brian Curtin52173d42010-12-02 18:29:18 +000010639#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010640static int
Brian Curtin52173d42010-12-02 18:29:18 +000010641enable_symlink()
10642{
10643 HANDLE tok;
10644 TOKEN_PRIVILEGES tok_priv;
10645 LUID luid;
10646 int meth_idx = 0;
10647
10648 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010649 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010650
10651 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010652 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010653
10654 tok_priv.PrivilegeCount = 1;
10655 tok_priv.Privileges[0].Luid = luid;
10656 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
10657
10658 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
10659 sizeof(TOKEN_PRIVILEGES),
10660 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010661 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010662
Brian Curtin3b4499c2010-12-28 14:31:47 +000010663 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
10664 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000010665}
10666#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
10667
Barry Warsaw4a342091996-12-19 23:50:02 +000010668static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000010669all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000010670{
Guido van Rossum94f6f721999-01-06 18:42:14 +000010671#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010673#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010674#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010676#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010677#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010679#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010680#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010682#endif
Fred Drakec9680921999-12-13 16:37:25 +000010683#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010684 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000010685#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010686#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010687 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010688#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010689#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010691#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010692#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010694#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010695#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010697#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010698#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010700#endif
10701#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010703#endif
10704#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010706#endif
10707#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010709#endif
10710#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010712#endif
10713#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010715#endif
10716#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010718#endif
10719#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010721#endif
10722#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010724#endif
10725#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010727#endif
10728#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010730#endif
10731#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010733#endif
10734#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010736#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000010737#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010739#endif
10740#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010742#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010743#ifdef O_XATTR
10744 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
10745#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010746#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010748#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000010749#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010751#endif
10752#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010754#endif
Jesus Ceacf381202012-04-24 20:44:40 +020010755#ifdef O_EXEC
10756 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
10757#endif
10758#ifdef O_SEARCH
10759 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
10760#endif
10761#ifdef O_TTY_INIT
10762 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
10763#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010764#ifdef PRIO_PROCESS
10765 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
10766#endif
10767#ifdef PRIO_PGRP
10768 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
10769#endif
10770#ifdef PRIO_USER
10771 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
10772#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020010773#ifdef O_CLOEXEC
10774 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
10775#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010776#ifdef O_ACCMODE
10777 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
10778#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010779
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010780
Jesus Cea94363612012-06-22 18:32:07 +020010781#ifdef SEEK_HOLE
10782 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
10783#endif
10784#ifdef SEEK_DATA
10785 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
10786#endif
10787
Tim Peters5aa91602002-01-30 05:46:57 +000010788/* MS Windows */
10789#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 /* Don't inherit in child processes. */
10791 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010792#endif
10793#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000010794 /* Optimize for short life (keep in memory). */
10795 /* MS forgot to define this one with a non-underscore form too. */
10796 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010797#endif
10798#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 /* Automatically delete when last handle is closed. */
10800 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010801#endif
10802#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000010803 /* Optimize for random access. */
10804 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010805#endif
10806#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010807 /* Optimize for sequential access. */
10808 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010809#endif
10810
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010811/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010812#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010813 /* Send a SIGIO signal whenever input or output
10814 becomes available on file descriptor */
10815 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010816#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010817#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 /* Direct disk access. */
10819 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010820#endif
10821#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000010822 /* Must be a directory. */
10823 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010824#endif
10825#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 /* Do not follow links. */
10827 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010828#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010829#ifdef O_NOLINKS
10830 /* Fails if link count of the named file is greater than 1 */
10831 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
10832#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010833#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 /* Do not update the access time. */
10835 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010836#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000010837
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010839#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010840 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010841#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010842#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010843 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010844#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010845#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010847#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010848#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010849 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010850#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010851#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010853#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010854#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010856#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010857#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010859#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010860#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010862#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010863#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010865#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010866#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010868#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010869#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010871#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010872#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010874#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010875#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010877#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010878#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010880#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010881#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010883#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010884#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010886#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010887#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010889#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010890
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010891 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010892#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010893 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010894#endif /* ST_RDONLY */
10895#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010896 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010897#endif /* ST_NOSUID */
10898
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010899 /* FreeBSD sendfile() constants */
10900#ifdef SF_NODISKIO
10901 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
10902#endif
10903#ifdef SF_MNOWAIT
10904 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
10905#endif
10906#ifdef SF_SYNC
10907 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
10908#endif
10909
Ross Lagerwall7807c352011-03-17 20:20:30 +020010910 /* constants for posix_fadvise */
10911#ifdef POSIX_FADV_NORMAL
10912 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
10913#endif
10914#ifdef POSIX_FADV_SEQUENTIAL
10915 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
10916#endif
10917#ifdef POSIX_FADV_RANDOM
10918 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
10919#endif
10920#ifdef POSIX_FADV_NOREUSE
10921 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
10922#endif
10923#ifdef POSIX_FADV_WILLNEED
10924 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
10925#endif
10926#ifdef POSIX_FADV_DONTNEED
10927 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
10928#endif
10929
10930 /* constants for waitid */
10931#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
10932 if (ins(d, "P_PID", (long)P_PID)) return -1;
10933 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
10934 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
10935#endif
10936#ifdef WEXITED
10937 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
10938#endif
10939#ifdef WNOWAIT
10940 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
10941#endif
10942#ifdef WSTOPPED
10943 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
10944#endif
10945#ifdef CLD_EXITED
10946 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
10947#endif
10948#ifdef CLD_DUMPED
10949 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
10950#endif
10951#ifdef CLD_TRAPPED
10952 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
10953#endif
10954#ifdef CLD_CONTINUED
10955 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
10956#endif
10957
10958 /* constants for lockf */
10959#ifdef F_LOCK
10960 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
10961#endif
10962#ifdef F_TLOCK
10963 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
10964#endif
10965#ifdef F_ULOCK
10966 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
10967#endif
10968#ifdef F_TEST
10969 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
10970#endif
10971
Guido van Rossum246bc171999-02-01 23:54:31 +000010972#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
10974 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
10975 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
10976 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
10977 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000010978#endif
10979
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010980#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020010981 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010982 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
10983 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
10984#ifdef SCHED_SPORADIC
10985 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
10986#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010987#ifdef SCHED_BATCH
10988 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
10989#endif
10990#ifdef SCHED_IDLE
10991 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
10992#endif
10993#ifdef SCHED_RESET_ON_FORK
10994 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
10995#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020010996#ifdef SCHED_SYS
10997 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
10998#endif
10999#ifdef SCHED_IA
11000 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11001#endif
11002#ifdef SCHED_FSS
11003 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11004#endif
11005#ifdef SCHED_FX
11006 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11007#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011008#endif
11009
Benjamin Peterson9428d532011-09-14 11:45:52 -040011010#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011011 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11012 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11013 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11014#endif
11015
Victor Stinner8b905bd2011-10-25 13:34:04 +020011016#ifdef RTLD_LAZY
11017 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11018#endif
11019#ifdef RTLD_NOW
11020 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11021#endif
11022#ifdef RTLD_GLOBAL
11023 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11024#endif
11025#ifdef RTLD_LOCAL
11026 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11027#endif
11028#ifdef RTLD_NODELETE
11029 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11030#endif
11031#ifdef RTLD_NOLOAD
11032 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11033#endif
11034#ifdef RTLD_DEEPBIND
11035 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11036#endif
11037
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011039}
11040
11041
Tim Peters5aa91602002-01-30 05:46:57 +000011042#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011043#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011044#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011045
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011046#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011047#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011048#define MODNAME "posix"
11049#endif
11050
Martin v. Löwis1a214512008-06-11 05:26:20 +000011051static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 PyModuleDef_HEAD_INIT,
11053 MODNAME,
11054 posix__doc__,
11055 -1,
11056 posix_methods,
11057 NULL,
11058 NULL,
11059 NULL,
11060 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011061};
11062
11063
Larry Hastings9cf065c2012-06-22 16:30:09 -070011064static char *have_functions[] = {
11065
11066#ifdef HAVE_FACCESSAT
11067 "HAVE_FACCESSAT",
11068#endif
11069
11070#ifdef HAVE_FCHDIR
11071 "HAVE_FCHDIR",
11072#endif
11073
11074#ifdef HAVE_FCHMOD
11075 "HAVE_FCHMOD",
11076#endif
11077
11078#ifdef HAVE_FCHMODAT
11079 "HAVE_FCHMODAT",
11080#endif
11081
11082#ifdef HAVE_FCHOWN
11083 "HAVE_FCHOWN",
11084#endif
11085
11086#ifdef HAVE_FEXECVE
11087 "HAVE_FEXECVE",
11088#endif
11089
11090#ifdef HAVE_FDOPENDIR
11091 "HAVE_FDOPENDIR",
11092#endif
11093
Georg Brandl306336b2012-06-24 12:55:33 +020011094#ifdef HAVE_FPATHCONF
11095 "HAVE_FPATHCONF",
11096#endif
11097
Larry Hastings9cf065c2012-06-22 16:30:09 -070011098#ifdef HAVE_FSTATAT
11099 "HAVE_FSTATAT",
11100#endif
11101
11102#ifdef HAVE_FSTATVFS
11103 "HAVE_FSTATVFS",
11104#endif
11105
Georg Brandl306336b2012-06-24 12:55:33 +020011106#ifdef HAVE_FTRUNCATE
11107 "HAVE_FTRUNCATE",
11108#endif
11109
Larry Hastings9cf065c2012-06-22 16:30:09 -070011110#ifdef HAVE_FUTIMENS
11111 "HAVE_FUTIMENS",
11112#endif
11113
11114#ifdef HAVE_FUTIMES
11115 "HAVE_FUTIMES",
11116#endif
11117
11118#ifdef HAVE_FUTIMESAT
11119 "HAVE_FUTIMESAT",
11120#endif
11121
11122#ifdef HAVE_LINKAT
11123 "HAVE_LINKAT",
11124#endif
11125
11126#ifdef HAVE_LCHFLAGS
11127 "HAVE_LCHFLAGS",
11128#endif
11129
11130#ifdef HAVE_LCHMOD
11131 "HAVE_LCHMOD",
11132#endif
11133
11134#ifdef HAVE_LCHOWN
11135 "HAVE_LCHOWN",
11136#endif
11137
11138#ifdef HAVE_LSTAT
11139 "HAVE_LSTAT",
11140#endif
11141
11142#ifdef HAVE_LUTIMES
11143 "HAVE_LUTIMES",
11144#endif
11145
11146#ifdef HAVE_MKDIRAT
11147 "HAVE_MKDIRAT",
11148#endif
11149
11150#ifdef HAVE_MKFIFOAT
11151 "HAVE_MKFIFOAT",
11152#endif
11153
11154#ifdef HAVE_MKNODAT
11155 "HAVE_MKNODAT",
11156#endif
11157
11158#ifdef HAVE_OPENAT
11159 "HAVE_OPENAT",
11160#endif
11161
11162#ifdef HAVE_READLINKAT
11163 "HAVE_READLINKAT",
11164#endif
11165
11166#ifdef HAVE_RENAMEAT
11167 "HAVE_RENAMEAT",
11168#endif
11169
11170#ifdef HAVE_SYMLINKAT
11171 "HAVE_SYMLINKAT",
11172#endif
11173
11174#ifdef HAVE_UNLINKAT
11175 "HAVE_UNLINKAT",
11176#endif
11177
11178#ifdef HAVE_UTIMENSAT
11179 "HAVE_UTIMENSAT",
11180#endif
11181
11182#ifdef MS_WINDOWS
11183 "MS_WINDOWS",
11184#endif
11185
11186 NULL
11187};
11188
11189
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011190PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011191INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011192{
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011194 PyObject *list;
11195 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011196
Brian Curtin52173d42010-12-02 18:29:18 +000011197#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011198 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011199#endif
11200
Victor Stinner8c62be82010-05-06 00:08:46 +000011201 m = PyModule_Create(&posixmodule);
11202 if (m == NULL)
11203 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011204
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 /* Initialize environ dictionary */
11206 v = convertenviron();
11207 Py_XINCREF(v);
11208 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11209 return NULL;
11210 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011211
Victor Stinner8c62be82010-05-06 00:08:46 +000011212 if (all_ins(m))
11213 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011214
Victor Stinner8c62be82010-05-06 00:08:46 +000011215 if (setup_confname_tables(m))
11216 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011217
Victor Stinner8c62be82010-05-06 00:08:46 +000011218 Py_INCREF(PyExc_OSError);
11219 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011220
Guido van Rossumb3d39562000-01-31 18:41:26 +000011221#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011222 if (posix_putenv_garbage == NULL)
11223 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011224#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011225
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011227#if defined(HAVE_WAITID) && !defined(__APPLE__)
11228 waitid_result_desc.name = MODNAME ".waitid_result";
11229 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11230#endif
11231
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 stat_result_desc.name = MODNAME ".stat_result";
11233 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11234 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11235 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11236 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11237 structseq_new = StatResultType.tp_new;
11238 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011239
Victor Stinner8c62be82010-05-06 00:08:46 +000011240 statvfs_result_desc.name = MODNAME ".statvfs_result";
11241 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011242#ifdef NEED_TICKS_PER_SECOND
11243# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011245# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011246 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011247# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011248 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011249# endif
11250#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011251
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011252#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011253 sched_param_desc.name = MODNAME ".sched_param";
11254 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11255 SchedParamType.tp_new = sched_param_new;
11256#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011257
11258 /* initialize TerminalSize_info */
11259 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011260 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011261#if defined(HAVE_WAITID) && !defined(__APPLE__)
11262 Py_INCREF((PyObject*) &WaitidResultType);
11263 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11264#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 Py_INCREF((PyObject*) &StatResultType);
11266 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11267 Py_INCREF((PyObject*) &StatVFSResultType);
11268 PyModule_AddObject(m, "statvfs_result",
11269 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011270
11271#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011272 Py_INCREF(&SchedParamType);
11273 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011274#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011275
Larry Hastings605a62d2012-06-24 04:33:36 -070011276 times_result_desc.name = MODNAME ".times_result";
11277 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11278 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11279
11280 uname_result_desc.name = MODNAME ".uname_result";
11281 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11282 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11283
Thomas Wouters477c8d52006-05-27 19:21:47 +000011284#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 /*
11286 * Step 2 of weak-linking support on Mac OS X.
11287 *
11288 * The code below removes functions that are not available on the
11289 * currently active platform.
11290 *
11291 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011292 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011293 * OSX 10.4.
11294 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011295#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 if (fstatvfs == NULL) {
11297 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11298 return NULL;
11299 }
11300 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011301#endif /* HAVE_FSTATVFS */
11302
11303#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 if (statvfs == NULL) {
11305 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11306 return NULL;
11307 }
11308 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011309#endif /* HAVE_STATVFS */
11310
11311# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 if (lchown == NULL) {
11313 if (PyObject_DelAttrString(m, "lchown") == -1) {
11314 return NULL;
11315 }
11316 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011317#endif /* HAVE_LCHOWN */
11318
11319
11320#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011321
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011322 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011323 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11324
Larry Hastings6fe20b32012-04-19 15:07:49 -070011325 billion = PyLong_FromLong(1000000000);
11326 if (!billion)
11327 return NULL;
11328
Larry Hastings9cf065c2012-06-22 16:30:09 -070011329 /* suppress "function not used" warnings */
11330 {
11331 int ignored;
11332 fd_specified("", -1);
11333 follow_symlinks_specified("", 1);
11334 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11335 dir_fd_converter(Py_None, &ignored);
11336 dir_fd_unavailable(Py_None, &ignored);
11337 }
11338
11339 /*
11340 * provide list of locally available functions
11341 * so os.py can populate support_* lists
11342 */
11343 list = PyList_New(0);
11344 if (!list)
11345 return NULL;
11346 for (trace = have_functions; *trace; trace++) {
11347 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11348 if (!unicode)
11349 return NULL;
11350 if (PyList_Append(list, unicode))
11351 return NULL;
11352 Py_DECREF(unicode);
11353 }
11354 PyModule_AddObject(m, "_have_functions", list);
11355
11356 initialized = 1;
11357
Victor Stinner8c62be82010-05-06 00:08:46 +000011358 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011359
Guido van Rossumb6775db1994-08-01 11:34:53 +000011360}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011361
11362#ifdef __cplusplus
11363}
11364#endif