blob: 8cedb9eb1652c0d6849a0362932a6de400efcd18 [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
399_fd_converter(PyObject *o, int *p, int default_value) {
400 long long_value;
401 if (o == Py_None) {
402 *p = default_value;
403 return 1;
404 }
405 if (PyFloat_Check(o)) {
406 PyErr_SetString(PyExc_TypeError,
407 "integer argument expected, got float" );
408 return 0;
409 }
410 long_value = PyLong_AsLong(o);
411 if (long_value == -1 && PyErr_Occurred())
412 return 0;
413 if (long_value > INT_MAX) {
414 PyErr_SetString(PyExc_OverflowError,
415 "signed integer is greater than maximum");
416 return 0;
417 }
418 if (long_value < INT_MIN) {
419 PyErr_SetString(PyExc_OverflowError,
420 "signed integer is less than minimum");
421 return 0;
422 }
423 *p = (int)long_value;
424 return 1;
425}
426
427static int
428dir_fd_converter(PyObject *o, void *p) {
429 return _fd_converter(o, (int *)p, DEFAULT_DIR_FD);
430}
431
432
433
434/*
435 * A PyArg_ParseTuple "converter" function
436 * that handles filesystem paths in the manner
437 * preferred by the os module.
438 *
439 * path_converter accepts (Unicode) strings and their
440 * subclasses, and bytes and their subclasses. What
441 * it does with the argument depends on the platform:
442 *
443 * * On Windows, if we get a (Unicode) string we
444 * extract the wchar_t * and return it; if we get
445 * bytes we extract the char * and return that.
446 *
447 * * On all other platforms, strings are encoded
448 * to bytes using PyUnicode_FSConverter, then we
449 * extract the char * from the bytes object and
450 * return that.
451 *
452 * path_converter also optionally accepts signed
453 * integers (representing open file descriptors) instead
454 * of path strings.
455 *
456 * Input fields:
457 * path.nullable
458 * If nonzero, the path is permitted to be None.
459 * path.allow_fd
460 * If nonzero, the path is permitted to be a file handle
461 * (a signed int) instead of a string.
462 * path.function_name
463 * If non-NULL, path_converter will use that as the name
464 * of the function in error messages.
465 * (If path.argument_name is NULL it omits the function name.)
466 * path.argument_name
467 * If non-NULL, path_converter will use that as the name
468 * of the parameter in error messages.
469 * (If path.argument_name is NULL it uses "path".)
470 *
471 * Output fields:
472 * path.wide
473 * Points to the path if it was expressed as Unicode
474 * and was not encoded. (Only used on Windows.)
475 * path.narrow
476 * Points to the path if it was expressed as bytes,
477 * or it was Unicode and was encoded to bytes.
478 * path.fd
479 * Contains a file descriptor if path.accept_fd was true
480 * and the caller provided a signed integer instead of any
481 * sort of string.
482 *
483 * WARNING: if your "path" parameter is optional, and is
484 * unspecified, path_converter will never get called.
485 * So if you set allow_fd, you *MUST* initialize path.fd = -1
486 * yourself!
487 * path.length
488 * The length of the path in characters, if specified as
489 * a string.
490 * path.object
491 * The original object passed in.
492 * path.cleanup
493 * For internal use only. May point to a temporary object.
494 * (Pay no attention to the man behind the curtain.)
495 *
496 * At most one of path.wide or path.narrow will be non-NULL.
497 * If path was None and path.nullable was set,
498 * or if path was an integer and path.allow_fd was set,
499 * both path.wide and path.narrow will be NULL
500 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200501 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700502 * path_converter takes care to not write to the path_t
503 * unless it's successful. However it must reset the
504 * "cleanup" field each time it's called.
505 *
506 * Use as follows:
507 * path_t path;
508 * memset(&path, 0, sizeof(path));
509 * PyArg_ParseTuple(args, "O&", path_converter, &path);
510 * // ... use values from path ...
511 * path_cleanup(&path);
512 *
513 * (Note that if PyArg_Parse fails you don't need to call
514 * path_cleanup(). However it is safe to do so.)
515 */
516typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100517 const char *function_name;
518 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700519 int nullable;
520 int allow_fd;
521 wchar_t *wide;
522 char *narrow;
523 int fd;
524 Py_ssize_t length;
525 PyObject *object;
526 PyObject *cleanup;
527} path_t;
528
529static void
530path_cleanup(path_t *path) {
531 if (path->cleanup) {
532 Py_DECREF(path->cleanup);
533 path->cleanup = NULL;
534 }
535}
536
537static int
538path_converter(PyObject *o, void *p) {
539 path_t *path = (path_t *)p;
540 PyObject *unicode, *bytes;
541 Py_ssize_t length;
542 char *narrow;
543
544#define FORMAT_EXCEPTION(exc, fmt) \
545 PyErr_Format(exc, "%s%s" fmt, \
546 path->function_name ? path->function_name : "", \
547 path->function_name ? ": " : "", \
548 path->argument_name ? path->argument_name : "path")
549
550 /* Py_CLEANUP_SUPPORTED support */
551 if (o == NULL) {
552 path_cleanup(path);
553 return 1;
554 }
555
556 /* ensure it's always safe to call path_cleanup() */
557 path->cleanup = NULL;
558
559 if (o == Py_None) {
560 if (!path->nullable) {
561 FORMAT_EXCEPTION(PyExc_TypeError,
562 "can't specify None for %s argument");
563 return 0;
564 }
565 path->wide = NULL;
566 path->narrow = NULL;
567 path->length = 0;
568 path->object = o;
569 path->fd = -1;
570 return 1;
571 }
572
573 unicode = PyUnicode_FromObject(o);
574 if (unicode) {
575#ifdef MS_WINDOWS
576 wchar_t *wide;
577 length = PyUnicode_GET_SIZE(unicode);
578 if (length > 32767) {
579 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
580 Py_DECREF(unicode);
581 return 0;
582 }
583
584 wide = PyUnicode_AsUnicode(unicode);
585 if (!wide) {
586 Py_DECREF(unicode);
587 return 0;
588 }
589
590 path->wide = wide;
591 path->narrow = NULL;
592 path->length = length;
593 path->object = o;
594 path->fd = -1;
595 path->cleanup = unicode;
596 return Py_CLEANUP_SUPPORTED;
597#else
598 int converted = PyUnicode_FSConverter(unicode, &bytes);
599 Py_DECREF(unicode);
600 if (!converted)
601 bytes = NULL;
602#endif
603 }
604 else {
605 PyErr_Clear();
606 bytes = PyBytes_FromObject(o);
607 if (!bytes) {
608 PyErr_Clear();
609 if (path->allow_fd) {
610 int fd;
611 /*
612 * note: _fd_converter always permits None.
613 * but we've already done our None check.
614 * so o cannot be None at this point.
615 */
616 int result = _fd_converter(o, &fd, -1);
617 if (result) {
618 path->wide = NULL;
619 path->narrow = NULL;
620 path->length = 0;
621 path->object = o;
622 path->fd = fd;
623 return result;
624 }
625 }
626 }
627 }
628
629 if (!bytes) {
630 if (!PyErr_Occurred())
631 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
632 return 0;
633 }
634
635#ifdef MS_WINDOWS
636 if (win32_warn_bytes_api()) {
637 Py_DECREF(bytes);
638 return 0;
639 }
640#endif
641
642 length = PyBytes_GET_SIZE(bytes);
643#ifdef MS_WINDOWS
644 if (length > MAX_PATH) {
645 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
646 Py_DECREF(bytes);
647 return 0;
648 }
649#endif
650
651 narrow = PyBytes_AS_STRING(bytes);
652 if (length != strlen(narrow)) {
653 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
654 Py_DECREF(bytes);
655 return 0;
656 }
657
658 path->wide = NULL;
659 path->narrow = narrow;
660 path->length = length;
661 path->object = o;
662 path->fd = -1;
663 path->cleanup = bytes;
664 return Py_CLEANUP_SUPPORTED;
665}
666
667static void
668argument_unavailable_error(char *function_name, char *argument_name) {
669 PyErr_Format(PyExc_NotImplementedError,
670 "%s%s%s unavailable on this platform",
671 (function_name != NULL) ? function_name : "",
672 (function_name != NULL) ? ": ": "",
673 argument_name);
674}
675
676static int
677dir_fd_unavailable(PyObject *o, void *p) {
678 int *dir_fd = (int *)p;
679 int return_value = _fd_converter(o, dir_fd, DEFAULT_DIR_FD);
680 if (!return_value)
681 return 0;
682 if (*dir_fd == DEFAULT_DIR_FD)
683 return 1;
684 argument_unavailable_error(NULL, "dir_fd");
685 return 0;
686}
687
688static int
689fd_specified(char *function_name, int fd) {
690 if (fd == -1)
691 return 0;
692
693 argument_unavailable_error(function_name, "fd");
694 return 1;
695}
696
697static int
698follow_symlinks_specified(char *function_name, int follow_symlinks) {
699 if (follow_symlinks)
700 return 0;
701
702 argument_unavailable_error(function_name, "follow_symlinks");
703 return 1;
704}
705
706static int
707path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
708 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
709 PyErr_Format(PyExc_ValueError,
710 "%s: can't specify dir_fd without matching path",
711 function_name);
712 return 1;
713 }
714 return 0;
715}
716
717static int
718dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
719 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
720 PyErr_Format(PyExc_ValueError,
721 "%s: can't specify both dir_fd and fd",
722 function_name);
723 return 1;
724 }
725 return 0;
726}
727
728static int
729fd_and_follow_symlinks_invalid(char *function_name, int fd,
730 int follow_symlinks) {
731 if ((fd > 0) && (!follow_symlinks)) {
732 PyErr_Format(PyExc_ValueError,
733 "%s: cannot use fd and follow_symlinks together",
734 function_name);
735 return 1;
736 }
737 return 0;
738}
739
740static int
741dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
742 int follow_symlinks) {
743 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
744 PyErr_Format(PyExc_ValueError,
745 "%s: cannot use dir_fd and follow_symlinks together",
746 function_name);
747 return 1;
748 }
749 return 0;
750}
751
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200752/* A helper used by a number of POSIX-only functions */
753#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000754static int
755_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000756{
757#if !defined(HAVE_LARGEFILE_SUPPORT)
758 *((off_t*)addr) = PyLong_AsLong(arg);
759#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000760 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000761#endif
762 if (PyErr_Occurred())
763 return 0;
764 return 1;
765}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200766#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000767
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000768#if defined _MSC_VER && _MSC_VER >= 1400
769/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
770 * valid and throw an assertion if it isn't.
771 * Normally, an invalid fd is likely to be a C program error and therefore
772 * an assertion can be useful, but it does contradict the POSIX standard
773 * which for write(2) states:
774 * "Otherwise, -1 shall be returned and errno set to indicate the error."
775 * "[EBADF] The fildes argument is not a valid file descriptor open for
776 * writing."
777 * Furthermore, python allows the user to enter any old integer
778 * as a fd and should merely raise a python exception on error.
779 * The Microsoft CRT doesn't provide an official way to check for the
780 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000781 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000782 * internal structures involved.
783 * The structures below must be updated for each version of visual studio
784 * according to the file internal.h in the CRT source, until MS comes
785 * up with a less hacky way to do this.
786 * (all of this is to avoid globally modifying the CRT behaviour using
787 * _set_invalid_parameter_handler() and _CrtSetReportMode())
788 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000789/* The actual size of the structure is determined at runtime.
790 * Only the first items must be present.
791 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000792typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000793 intptr_t osfhnd;
794 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000795} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000796
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000797extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000798#define IOINFO_L2E 5
799#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
800#define IOINFO_ARRAYS 64
801#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
802#define FOPEN 0x01
803#define _NO_CONSOLE_FILENO (intptr_t)-2
804
805/* This function emulates what the windows CRT does to validate file handles */
806int
807_PyVerify_fd(int fd)
808{
Victor Stinner8c62be82010-05-06 00:08:46 +0000809 const int i1 = fd >> IOINFO_L2E;
810 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000811
Antoine Pitrou22e41552010-08-15 18:07:50 +0000812 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000813
Victor Stinner8c62be82010-05-06 00:08:46 +0000814 /* Determine the actual size of the ioinfo structure,
815 * as used by the CRT loaded in memory
816 */
817 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
818 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
819 }
820 if (sizeof_ioinfo == 0) {
821 /* This should not happen... */
822 goto fail;
823 }
824
825 /* See that it isn't a special CLEAR fileno */
826 if (fd != _NO_CONSOLE_FILENO) {
827 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
828 * we check pointer validity and other info
829 */
830 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
831 /* finally, check that the file is open */
832 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
833 if (info->osfile & FOPEN) {
834 return 1;
835 }
836 }
837 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000838 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000839 errno = EBADF;
840 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000841}
842
843/* the special case of checking dup2. The target fd must be in a sensible range */
844static int
845_PyVerify_fd_dup2(int fd1, int fd2)
846{
Victor Stinner8c62be82010-05-06 00:08:46 +0000847 if (!_PyVerify_fd(fd1))
848 return 0;
849 if (fd2 == _NO_CONSOLE_FILENO)
850 return 0;
851 if ((unsigned)fd2 < _NHANDLE_)
852 return 1;
853 else
854 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000855}
856#else
857/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
858#define _PyVerify_fd_dup2(A, B) (1)
859#endif
860
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000861#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000862/* The following structure was copied from
863 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
864 include doesn't seem to be present in the Windows SDK (at least as included
865 with Visual Studio Express). */
866typedef struct _REPARSE_DATA_BUFFER {
867 ULONG ReparseTag;
868 USHORT ReparseDataLength;
869 USHORT Reserved;
870 union {
871 struct {
872 USHORT SubstituteNameOffset;
873 USHORT SubstituteNameLength;
874 USHORT PrintNameOffset;
875 USHORT PrintNameLength;
876 ULONG Flags;
877 WCHAR PathBuffer[1];
878 } SymbolicLinkReparseBuffer;
879
880 struct {
881 USHORT SubstituteNameOffset;
882 USHORT SubstituteNameLength;
883 USHORT PrintNameOffset;
884 USHORT PrintNameLength;
885 WCHAR PathBuffer[1];
886 } MountPointReparseBuffer;
887
888 struct {
889 UCHAR DataBuffer[1];
890 } GenericReparseBuffer;
891 };
892} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
893
894#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
895 GenericReparseBuffer)
896#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
897
898static int
Brian Curtind25aef52011-06-13 15:16:04 -0500899win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000900{
901 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
902 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
903 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000904
905 if (0 == DeviceIoControl(
906 reparse_point_handle,
907 FSCTL_GET_REPARSE_POINT,
908 NULL, 0, /* in buffer */
909 target_buffer, sizeof(target_buffer),
910 &n_bytes_returned,
911 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500912 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000913
914 if (reparse_tag)
915 *reparse_tag = rdb->ReparseTag;
916
Brian Curtind25aef52011-06-13 15:16:04 -0500917 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000918}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100919
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000920#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000921
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000922/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000923#ifdef WITH_NEXT_FRAMEWORK
924/* On Darwin/MacOSX a shared library or framework has no access to
925** environ directly, we must obtain it with _NSGetEnviron().
926*/
927#include <crt_externs.h>
928static char **environ;
929#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000931#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000932
Barry Warsaw53699e91996-12-10 23:23:01 +0000933static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000934convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000935{
Victor Stinner8c62be82010-05-06 00:08:46 +0000936 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000937#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000938 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000939#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000940 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000941#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000942
Victor Stinner8c62be82010-05-06 00:08:46 +0000943 d = PyDict_New();
944 if (d == NULL)
945 return NULL;
946#ifdef WITH_NEXT_FRAMEWORK
947 if (environ == NULL)
948 environ = *_NSGetEnviron();
949#endif
950#ifdef MS_WINDOWS
951 /* _wenviron must be initialized in this way if the program is started
952 through main() instead of wmain(). */
953 _wgetenv(L"");
954 if (_wenviron == NULL)
955 return d;
956 /* This part ignores errors */
957 for (e = _wenviron; *e != NULL; e++) {
958 PyObject *k;
959 PyObject *v;
960 wchar_t *p = wcschr(*e, L'=');
961 if (p == NULL)
962 continue;
963 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
964 if (k == NULL) {
965 PyErr_Clear();
966 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000967 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000968 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
969 if (v == NULL) {
970 PyErr_Clear();
971 Py_DECREF(k);
972 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000973 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000974 if (PyDict_GetItem(d, k) == NULL) {
975 if (PyDict_SetItem(d, k, v) != 0)
976 PyErr_Clear();
977 }
978 Py_DECREF(k);
979 Py_DECREF(v);
980 }
981#else
982 if (environ == NULL)
983 return d;
984 /* This part ignores errors */
985 for (e = environ; *e != NULL; e++) {
986 PyObject *k;
987 PyObject *v;
988 char *p = strchr(*e, '=');
989 if (p == NULL)
990 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000991 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000992 if (k == NULL) {
993 PyErr_Clear();
994 continue;
995 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000996 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000997 if (v == NULL) {
998 PyErr_Clear();
999 Py_DECREF(k);
1000 continue;
1001 }
1002 if (PyDict_GetItem(d, k) == NULL) {
1003 if (PyDict_SetItem(d, k, v) != 0)
1004 PyErr_Clear();
1005 }
1006 Py_DECREF(k);
1007 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001008 }
1009#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001010 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001011}
1012
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001013/* Set a POSIX-specific error from errno, and return NULL */
1014
Barry Warsawd58d7641998-07-23 16:14:40 +00001015static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001016posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001017{
Victor Stinner8c62be82010-05-06 00:08:46 +00001018 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001019}
Mark Hammondef8b6542001-05-13 08:04:26 +00001020
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001021#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001022static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001023win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001024{
Victor Stinner8c62be82010-05-06 00:08:46 +00001025 /* XXX We should pass the function name along in the future.
1026 (winreg.c also wants to pass the function name.)
1027 This would however require an additional param to the
1028 Windows error object, which is non-trivial.
1029 */
1030 errno = GetLastError();
1031 if (filename)
1032 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1033 else
1034 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001035}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001036
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001037static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001038win32_error_object(char* function, PyObject* filename)
1039{
1040 /* XXX - see win32_error for comments on 'function' */
1041 errno = GetLastError();
1042 if (filename)
1043 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1044 PyExc_WindowsError,
1045 errno,
1046 filename);
1047 else
1048 return PyErr_SetFromWindowsErr(errno);
1049}
1050
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001051#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001052
Larry Hastings9cf065c2012-06-22 16:30:09 -07001053static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001054path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001055{
1056#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001057 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1058 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001059#else
Victor Stinner292c8352012-10-30 02:17:38 +01001060 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001061#endif
1062}
1063
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001064/* POSIX generic methods */
1065
Barry Warsaw53699e91996-12-10 23:23:01 +00001066static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001067posix_fildes(PyObject *fdobj, int (*func)(int))
1068{
Victor Stinner8c62be82010-05-06 00:08:46 +00001069 int fd;
1070 int res;
1071 fd = PyObject_AsFileDescriptor(fdobj);
1072 if (fd < 0)
1073 return NULL;
1074 if (!_PyVerify_fd(fd))
1075 return posix_error();
1076 Py_BEGIN_ALLOW_THREADS
1077 res = (*func)(fd);
1078 Py_END_ALLOW_THREADS
1079 if (res < 0)
1080 return posix_error();
1081 Py_INCREF(Py_None);
1082 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001083}
Guido van Rossum21142a01999-01-08 21:05:37 +00001084
1085static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001086posix_1str(const char *func_name, PyObject *args, char *format,
1087 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001088{
Victor Stinner292c8352012-10-30 02:17:38 +01001089 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001090 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001091 memset(&path, 0, sizeof(path));
1092 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001093 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001094 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001095 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001096 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001097 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001098 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001099 if (res < 0) {
1100 path_error(&path);
1101 path_cleanup(&path);
1102 return NULL;
1103 }
1104 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001105 Py_INCREF(Py_None);
1106 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001107}
1108
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001109
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001110#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001111/* This is a reimplementation of the C library's chdir function,
1112 but one that produces Win32 errors instead of DOS error codes.
1113 chdir is essentially a wrapper around SetCurrentDirectory; however,
1114 it also needs to set "magic" environment variables indicating
1115 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001116static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001117win32_chdir(LPCSTR path)
1118{
Victor Stinner8c62be82010-05-06 00:08:46 +00001119 char new_path[MAX_PATH+1];
1120 int result;
1121 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001122
Victor Stinner8c62be82010-05-06 00:08:46 +00001123 if(!SetCurrentDirectoryA(path))
1124 return FALSE;
1125 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1126 if (!result)
1127 return FALSE;
1128 /* In the ANSI API, there should not be any paths longer
1129 than MAX_PATH. */
1130 assert(result <= MAX_PATH+1);
1131 if (strncmp(new_path, "\\\\", 2) == 0 ||
1132 strncmp(new_path, "//", 2) == 0)
1133 /* UNC path, nothing to do. */
1134 return TRUE;
1135 env[1] = new_path[0];
1136 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001137}
1138
1139/* The Unicode version differs from the ANSI version
1140 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001141static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001142win32_wchdir(LPCWSTR path)
1143{
Victor Stinner8c62be82010-05-06 00:08:46 +00001144 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1145 int result;
1146 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001147
Victor Stinner8c62be82010-05-06 00:08:46 +00001148 if(!SetCurrentDirectoryW(path))
1149 return FALSE;
1150 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1151 if (!result)
1152 return FALSE;
1153 if (result > MAX_PATH+1) {
1154 new_path = malloc(result * sizeof(wchar_t));
1155 if (!new_path) {
1156 SetLastError(ERROR_OUTOFMEMORY);
1157 return FALSE;
1158 }
1159 result = GetCurrentDirectoryW(result, new_path);
1160 if (!result) {
1161 free(new_path);
1162 return FALSE;
1163 }
1164 }
1165 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1166 wcsncmp(new_path, L"//", 2) == 0)
1167 /* UNC path, nothing to do. */
1168 return TRUE;
1169 env[1] = new_path[0];
1170 result = SetEnvironmentVariableW(env, new_path);
1171 if (new_path != _new_path)
1172 free(new_path);
1173 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001174}
1175#endif
1176
Martin v. Löwis14694662006-02-03 12:54:16 +00001177#ifdef MS_WINDOWS
1178/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1179 - time stamps are restricted to second resolution
1180 - file modification times suffer from forth-and-back conversions between
1181 UTC and local time
1182 Therefore, we implement our own stat, based on the Win32 API directly.
1183*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001184#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001185
1186struct win32_stat{
1187 int st_dev;
1188 __int64 st_ino;
1189 unsigned short st_mode;
1190 int st_nlink;
1191 int st_uid;
1192 int st_gid;
1193 int st_rdev;
1194 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001195 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001196 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001197 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001198 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001199 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001200 int st_ctime_nsec;
1201};
1202
1203static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1204
1205static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001206FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001207{
Victor Stinner8c62be82010-05-06 00:08:46 +00001208 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1209 /* Cannot simply cast and dereference in_ptr,
1210 since it might not be aligned properly */
1211 __int64 in;
1212 memcpy(&in, in_ptr, sizeof(in));
1213 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001214 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001215}
1216
Thomas Wouters477c8d52006-05-27 19:21:47 +00001217static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001218time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001219{
Victor Stinner8c62be82010-05-06 00:08:46 +00001220 /* XXX endianness */
1221 __int64 out;
1222 out = time_in + secs_between_epochs;
1223 out = out * 10000000 + nsec_in / 100;
1224 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001225}
1226
Martin v. Löwis14694662006-02-03 12:54:16 +00001227/* Below, we *know* that ugo+r is 0444 */
1228#if _S_IREAD != 0400
1229#error Unsupported C library
1230#endif
1231static int
1232attributes_to_mode(DWORD attr)
1233{
Victor Stinner8c62be82010-05-06 00:08:46 +00001234 int m = 0;
1235 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1236 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1237 else
1238 m |= _S_IFREG;
1239 if (attr & FILE_ATTRIBUTE_READONLY)
1240 m |= 0444;
1241 else
1242 m |= 0666;
1243 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001244}
1245
1246static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001247attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001248{
Victor Stinner8c62be82010-05-06 00:08:46 +00001249 memset(result, 0, sizeof(*result));
1250 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1251 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1252 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1253 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1254 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001255 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001256 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001257 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1258 /* first clear the S_IFMT bits */
1259 result->st_mode ^= (result->st_mode & 0170000);
1260 /* now set the bits that make this a symlink */
1261 result->st_mode |= 0120000;
1262 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001263
Victor Stinner8c62be82010-05-06 00:08:46 +00001264 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001265}
1266
Guido van Rossumd8faa362007-04-27 19:54:29 +00001267static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001268attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001269{
Victor Stinner8c62be82010-05-06 00:08:46 +00001270 HANDLE hFindFile;
1271 WIN32_FIND_DATAA FileData;
1272 hFindFile = FindFirstFileA(pszFile, &FileData);
1273 if (hFindFile == INVALID_HANDLE_VALUE)
1274 return FALSE;
1275 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001276 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001277 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001278 info->dwFileAttributes = FileData.dwFileAttributes;
1279 info->ftCreationTime = FileData.ftCreationTime;
1280 info->ftLastAccessTime = FileData.ftLastAccessTime;
1281 info->ftLastWriteTime = FileData.ftLastWriteTime;
1282 info->nFileSizeHigh = FileData.nFileSizeHigh;
1283 info->nFileSizeLow = FileData.nFileSizeLow;
1284/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001285 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1286 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001287 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001288}
1289
1290static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001291attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001292{
Victor Stinner8c62be82010-05-06 00:08:46 +00001293 HANDLE hFindFile;
1294 WIN32_FIND_DATAW FileData;
1295 hFindFile = FindFirstFileW(pszFile, &FileData);
1296 if (hFindFile == INVALID_HANDLE_VALUE)
1297 return FALSE;
1298 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001299 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001300 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001301 info->dwFileAttributes = FileData.dwFileAttributes;
1302 info->ftCreationTime = FileData.ftCreationTime;
1303 info->ftLastAccessTime = FileData.ftLastAccessTime;
1304 info->ftLastWriteTime = FileData.ftLastWriteTime;
1305 info->nFileSizeHigh = FileData.nFileSizeHigh;
1306 info->nFileSizeLow = FileData.nFileSizeLow;
1307/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001308 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1309 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001310 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001311}
1312
Brian Curtind25aef52011-06-13 15:16:04 -05001313/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001314static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001315static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1316 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001317static int
Brian Curtind25aef52011-06-13 15:16:04 -05001318check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001319{
Brian Curtind25aef52011-06-13 15:16:04 -05001320 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001321 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1322 DWORD);
1323
Brian Curtind25aef52011-06-13 15:16:04 -05001324 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001325 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001326 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001327 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001328 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1329 "GetFinalPathNameByHandleA");
1330 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1331 "GetFinalPathNameByHandleW");
1332 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1333 Py_GetFinalPathNameByHandleW;
1334 }
1335 return has_GetFinalPathNameByHandle;
1336}
1337
1338static BOOL
1339get_target_path(HANDLE hdl, wchar_t **target_path)
1340{
1341 int buf_size, result_length;
1342 wchar_t *buf;
1343
1344 /* We have a good handle to the target, use it to determine
1345 the target path name (then we'll call lstat on it). */
1346 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1347 VOLUME_NAME_DOS);
1348 if(!buf_size)
1349 return FALSE;
1350
1351 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001352 if (!buf) {
1353 SetLastError(ERROR_OUTOFMEMORY);
1354 return FALSE;
1355 }
1356
Brian Curtind25aef52011-06-13 15:16:04 -05001357 result_length = Py_GetFinalPathNameByHandleW(hdl,
1358 buf, buf_size, VOLUME_NAME_DOS);
1359
1360 if(!result_length) {
1361 free(buf);
1362 return FALSE;
1363 }
1364
1365 if(!CloseHandle(hdl)) {
1366 free(buf);
1367 return FALSE;
1368 }
1369
1370 buf[result_length] = 0;
1371
1372 *target_path = buf;
1373 return TRUE;
1374}
1375
1376static int
1377win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1378 BOOL traverse);
1379static int
1380win32_xstat_impl(const char *path, struct win32_stat *result,
1381 BOOL traverse)
1382{
Victor Stinner26de69d2011-06-17 15:15:38 +02001383 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001384 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001385 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001386 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001387 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001388 const char *dot;
1389
Brian Curtind25aef52011-06-13 15:16:04 -05001390 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001391 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1392 traverse reparse point. */
1393 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001394 }
1395
Brian Curtinf5e76d02010-11-24 13:14:05 +00001396 hFile = CreateFileA(
1397 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001398 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001399 0, /* share mode */
1400 NULL, /* security attributes */
1401 OPEN_EXISTING,
1402 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001403 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1404 Because of this, calls like GetFinalPathNameByHandle will return
1405 the symlink path agin and not the actual final path. */
1406 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1407 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001408 NULL);
1409
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001410 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001411 /* Either the target doesn't exist, or we don't have access to
1412 get a handle to it. If the former, we need to return an error.
1413 If the latter, we can use attributes_from_dir. */
1414 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001415 return -1;
1416 /* Could not get attributes on open file. Fall back to
1417 reading the directory. */
1418 if (!attributes_from_dir(path, &info, &reparse_tag))
1419 /* Very strange. This should not fail now */
1420 return -1;
1421 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1422 if (traverse) {
1423 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001424 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001425 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001426 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001427 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001428 } else {
1429 if (!GetFileInformationByHandle(hFile, &info)) {
1430 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001431 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001432 }
1433 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001434 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1435 return -1;
1436
1437 /* Close the outer open file handle now that we're about to
1438 reopen it with different flags. */
1439 if (!CloseHandle(hFile))
1440 return -1;
1441
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001442 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001443 /* In order to call GetFinalPathNameByHandle we need to open
1444 the file without the reparse handling flag set. */
1445 hFile2 = CreateFileA(
1446 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1447 NULL, OPEN_EXISTING,
1448 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1449 NULL);
1450 if (hFile2 == INVALID_HANDLE_VALUE)
1451 return -1;
1452
1453 if (!get_target_path(hFile2, &target_path))
1454 return -1;
1455
1456 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001457 free(target_path);
1458 return code;
1459 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001460 } else
1461 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001462 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001463 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001464
1465 /* Set S_IEXEC if it is an .exe, .bat, ... */
1466 dot = strrchr(path, '.');
1467 if (dot) {
1468 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1469 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1470 result->st_mode |= 0111;
1471 }
1472 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001473}
1474
1475static int
Brian Curtind25aef52011-06-13 15:16:04 -05001476win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1477 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001478{
1479 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001480 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001481 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001482 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001483 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001484 const wchar_t *dot;
1485
Brian Curtind25aef52011-06-13 15:16:04 -05001486 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001487 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1488 traverse reparse point. */
1489 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001490 }
1491
Brian Curtinf5e76d02010-11-24 13:14:05 +00001492 hFile = CreateFileW(
1493 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001494 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001495 0, /* share mode */
1496 NULL, /* security attributes */
1497 OPEN_EXISTING,
1498 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001499 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1500 Because of this, calls like GetFinalPathNameByHandle will return
1501 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001502 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001503 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001504 NULL);
1505
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001506 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001507 /* Either the target doesn't exist, or we don't have access to
1508 get a handle to it. If the former, we need to return an error.
1509 If the latter, we can use attributes_from_dir. */
1510 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001511 return -1;
1512 /* Could not get attributes on open file. Fall back to
1513 reading the directory. */
1514 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1515 /* Very strange. This should not fail now */
1516 return -1;
1517 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1518 if (traverse) {
1519 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001520 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001521 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001522 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001523 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001524 } else {
1525 if (!GetFileInformationByHandle(hFile, &info)) {
1526 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001527 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001528 }
1529 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001530 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1531 return -1;
1532
1533 /* Close the outer open file handle now that we're about to
1534 reopen it with different flags. */
1535 if (!CloseHandle(hFile))
1536 return -1;
1537
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001538 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001539 /* In order to call GetFinalPathNameByHandle we need to open
1540 the file without the reparse handling flag set. */
1541 hFile2 = CreateFileW(
1542 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1543 NULL, OPEN_EXISTING,
1544 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1545 NULL);
1546 if (hFile2 == INVALID_HANDLE_VALUE)
1547 return -1;
1548
1549 if (!get_target_path(hFile2, &target_path))
1550 return -1;
1551
1552 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001553 free(target_path);
1554 return code;
1555 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001556 } else
1557 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001558 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001559 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001560
1561 /* Set S_IEXEC if it is an .exe, .bat, ... */
1562 dot = wcsrchr(path, '.');
1563 if (dot) {
1564 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1565 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1566 result->st_mode |= 0111;
1567 }
1568 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001569}
1570
1571static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001572win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001574 /* Protocol violation: we explicitly clear errno, instead of
1575 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001576 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001577 errno = 0;
1578 return code;
1579}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001580
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001581static int
1582win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1583{
1584 /* Protocol violation: we explicitly clear errno, instead of
1585 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001586 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001587 errno = 0;
1588 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001589}
Brian Curtind25aef52011-06-13 15:16:04 -05001590/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001591
1592 In Posix, stat automatically traverses symlinks and returns the stat
1593 structure for the target. In Windows, the equivalent GetFileAttributes by
1594 default does not traverse symlinks and instead returns attributes for
1595 the symlink.
1596
1597 Therefore, win32_lstat will get the attributes traditionally, and
1598 win32_stat will first explicitly resolve the symlink target and then will
1599 call win32_lstat on that result.
1600
Ezio Melotti4969f702011-03-15 05:59:46 +02001601 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001602
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001603static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001604win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001605{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001606 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001607}
1608
Victor Stinner8c62be82010-05-06 00:08:46 +00001609static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001610win32_lstat_w(const wchar_t* 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_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001613}
1614
1615static int
1616win32_stat(const char* path, struct win32_stat *result)
1617{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001618 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001619}
1620
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001621static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001622win32_stat_w(const wchar_t* path, struct win32_stat *result)
1623{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001624 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001625}
1626
1627static int
1628win32_fstat(int file_number, struct win32_stat *result)
1629{
Victor Stinner8c62be82010-05-06 00:08:46 +00001630 BY_HANDLE_FILE_INFORMATION info;
1631 HANDLE h;
1632 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001633
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001634 if (!_PyVerify_fd(file_number))
1635 h = INVALID_HANDLE_VALUE;
1636 else
1637 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001638
Victor Stinner8c62be82010-05-06 00:08:46 +00001639 /* Protocol violation: we explicitly clear errno, instead of
1640 setting it to a POSIX error. Callers should use GetLastError. */
1641 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001642
Victor Stinner8c62be82010-05-06 00:08:46 +00001643 if (h == INVALID_HANDLE_VALUE) {
1644 /* This is really a C library error (invalid file handle).
1645 We set the Win32 error to the closes one matching. */
1646 SetLastError(ERROR_INVALID_HANDLE);
1647 return -1;
1648 }
1649 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001650
Victor Stinner8c62be82010-05-06 00:08:46 +00001651 type = GetFileType(h);
1652 if (type == FILE_TYPE_UNKNOWN) {
1653 DWORD error = GetLastError();
1654 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001655 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001656 }
1657 /* else: valid but unknown file */
1658 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001659
Victor Stinner8c62be82010-05-06 00:08:46 +00001660 if (type != FILE_TYPE_DISK) {
1661 if (type == FILE_TYPE_CHAR)
1662 result->st_mode = _S_IFCHR;
1663 else if (type == FILE_TYPE_PIPE)
1664 result->st_mode = _S_IFIFO;
1665 return 0;
1666 }
1667
1668 if (!GetFileInformationByHandle(h, &info)) {
1669 return -1;
1670 }
1671
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001672 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001673 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001674 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1675 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001676}
1677
1678#endif /* MS_WINDOWS */
1679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001680PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001681"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001682This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001683 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001684or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1685\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001686Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1687or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001688\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001689See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001690
1691static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001692 {"st_mode", "protection bits"},
1693 {"st_ino", "inode"},
1694 {"st_dev", "device"},
1695 {"st_nlink", "number of hard links"},
1696 {"st_uid", "user ID of owner"},
1697 {"st_gid", "group ID of owner"},
1698 {"st_size", "total size, in bytes"},
1699 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1700 {NULL, "integer time of last access"},
1701 {NULL, "integer time of last modification"},
1702 {NULL, "integer time of last change"},
1703 {"st_atime", "time of last access"},
1704 {"st_mtime", "time of last modification"},
1705 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001706 {"st_atime_ns", "time of last access in nanoseconds"},
1707 {"st_mtime_ns", "time of last modification in nanoseconds"},
1708 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001709#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001710 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001711#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001712#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001713 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001714#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001715#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001716 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001717#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001718#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001719 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001720#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001721#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001722 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001723#endif
1724#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001725 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001726#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001727 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001728};
1729
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001730#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001731#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001732#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001733#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001734#endif
1735
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001736#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001737#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1738#else
1739#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1740#endif
1741
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001742#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001743#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1744#else
1745#define ST_RDEV_IDX ST_BLOCKS_IDX
1746#endif
1747
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001748#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1749#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1750#else
1751#define ST_FLAGS_IDX ST_RDEV_IDX
1752#endif
1753
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001754#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001755#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001756#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001757#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001758#endif
1759
1760#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1761#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1762#else
1763#define ST_BIRTHTIME_IDX ST_GEN_IDX
1764#endif
1765
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001766static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001767 "stat_result", /* name */
1768 stat_result__doc__, /* doc */
1769 stat_result_fields,
1770 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001771};
1772
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001774"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1775This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001776 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001777or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001778\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001779See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780
1781static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 {"f_bsize", },
1783 {"f_frsize", },
1784 {"f_blocks", },
1785 {"f_bfree", },
1786 {"f_bavail", },
1787 {"f_files", },
1788 {"f_ffree", },
1789 {"f_favail", },
1790 {"f_flag", },
1791 {"f_namemax",},
1792 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001793};
1794
1795static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001796 "statvfs_result", /* name */
1797 statvfs_result__doc__, /* doc */
1798 statvfs_result_fields,
1799 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001800};
1801
Ross Lagerwall7807c352011-03-17 20:20:30 +02001802#if defined(HAVE_WAITID) && !defined(__APPLE__)
1803PyDoc_STRVAR(waitid_result__doc__,
1804"waitid_result: Result from waitid.\n\n\
1805This object may be accessed either as a tuple of\n\
1806 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1807or via the attributes si_pid, si_uid, and so on.\n\
1808\n\
1809See os.waitid for more information.");
1810
1811static PyStructSequence_Field waitid_result_fields[] = {
1812 {"si_pid", },
1813 {"si_uid", },
1814 {"si_signo", },
1815 {"si_status", },
1816 {"si_code", },
1817 {0}
1818};
1819
1820static PyStructSequence_Desc waitid_result_desc = {
1821 "waitid_result", /* name */
1822 waitid_result__doc__, /* doc */
1823 waitid_result_fields,
1824 5
1825};
1826static PyTypeObject WaitidResultType;
1827#endif
1828
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001829static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001830static PyTypeObject StatResultType;
1831static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001832#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001833static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001834#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001835static newfunc structseq_new;
1836
1837static PyObject *
1838statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1839{
Victor Stinner8c62be82010-05-06 00:08:46 +00001840 PyStructSequence *result;
1841 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001842
Victor Stinner8c62be82010-05-06 00:08:46 +00001843 result = (PyStructSequence*)structseq_new(type, args, kwds);
1844 if (!result)
1845 return NULL;
1846 /* If we have been initialized from a tuple,
1847 st_?time might be set to None. Initialize it
1848 from the int slots. */
1849 for (i = 7; i <= 9; i++) {
1850 if (result->ob_item[i+3] == Py_None) {
1851 Py_DECREF(Py_None);
1852 Py_INCREF(result->ob_item[i]);
1853 result->ob_item[i+3] = result->ob_item[i];
1854 }
1855 }
1856 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001857}
1858
1859
1860
1861/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001862static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001863
1864PyDoc_STRVAR(stat_float_times__doc__,
1865"stat_float_times([newval]) -> oldval\n\n\
1866Determine whether os.[lf]stat represents time stamps as float objects.\n\
1867If newval is True, future calls to stat() return floats, if it is False,\n\
1868future calls return ints. \n\
1869If newval is omitted, return the current setting.\n");
1870
1871static PyObject*
1872stat_float_times(PyObject* self, PyObject *args)
1873{
Victor Stinner8c62be82010-05-06 00:08:46 +00001874 int newval = -1;
1875 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1876 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001877 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1878 "stat_float_times() is deprecated",
1879 1))
1880 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001881 if (newval == -1)
1882 /* Return old value */
1883 return PyBool_FromLong(_stat_float_times);
1884 _stat_float_times = newval;
1885 Py_INCREF(Py_None);
1886 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001887}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001888
Larry Hastings6fe20b32012-04-19 15:07:49 -07001889static PyObject *billion = NULL;
1890
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001891static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001892fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001893{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001894 PyObject *s = _PyLong_FromTime_t(sec);
1895 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1896 PyObject *s_in_ns = NULL;
1897 PyObject *ns_total = NULL;
1898 PyObject *float_s = NULL;
1899
1900 if (!(s && ns_fractional))
1901 goto exit;
1902
1903 s_in_ns = PyNumber_Multiply(s, billion);
1904 if (!s_in_ns)
1905 goto exit;
1906
1907 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1908 if (!ns_total)
1909 goto exit;
1910
Victor Stinner4195b5c2012-02-08 23:03:19 +01001911 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001912 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1913 if (!float_s)
1914 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001916 else {
1917 float_s = s;
1918 Py_INCREF(float_s);
1919 }
1920
1921 PyStructSequence_SET_ITEM(v, index, s);
1922 PyStructSequence_SET_ITEM(v, index+3, float_s);
1923 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1924 s = NULL;
1925 float_s = NULL;
1926 ns_total = NULL;
1927exit:
1928 Py_XDECREF(s);
1929 Py_XDECREF(ns_fractional);
1930 Py_XDECREF(s_in_ns);
1931 Py_XDECREF(ns_total);
1932 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001933}
1934
Tim Peters5aa91602002-01-30 05:46:57 +00001935/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001936 (used by posix_stat() and posix_fstat()) */
1937static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001938_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001939{
Victor Stinner8c62be82010-05-06 00:08:46 +00001940 unsigned long ansec, mnsec, cnsec;
1941 PyObject *v = PyStructSequence_New(&StatResultType);
1942 if (v == NULL)
1943 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001944
Victor Stinner8c62be82010-05-06 00:08:46 +00001945 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001946#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 PyStructSequence_SET_ITEM(v, 1,
1948 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001949#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001951#endif
1952#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001953 PyStructSequence_SET_ITEM(v, 2,
1954 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001955#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001956 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001957#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1959 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1960 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001961#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 PyStructSequence_SET_ITEM(v, 6,
1963 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001964#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001965 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001966#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001967
Martin v. Löwis14694662006-02-03 12:54:16 +00001968#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001969 ansec = st->st_atim.tv_nsec;
1970 mnsec = st->st_mtim.tv_nsec;
1971 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001972#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 ansec = st->st_atimespec.tv_nsec;
1974 mnsec = st->st_mtimespec.tv_nsec;
1975 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001976#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 ansec = st->st_atime_nsec;
1978 mnsec = st->st_mtime_nsec;
1979 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001980#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001981 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001982#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001983 fill_time(v, 7, st->st_atime, ansec);
1984 fill_time(v, 8, st->st_mtime, mnsec);
1985 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001986
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001987#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001988 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1989 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001990#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001991#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001992 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1993 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001994#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001995#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001996 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1997 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001998#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001999#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002000 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2001 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002002#endif
2003#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002004 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002005 PyObject *val;
2006 unsigned long bsec,bnsec;
2007 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002008#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002009 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002010#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002011 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002012#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002013 if (_stat_float_times) {
2014 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2015 } else {
2016 val = PyLong_FromLong((long)bsec);
2017 }
2018 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2019 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002020 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002021#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002022#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002023 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2024 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002025#endif
Fred Drake699f3522000-06-29 21:12:41 +00002026
Victor Stinner8c62be82010-05-06 00:08:46 +00002027 if (PyErr_Occurred()) {
2028 Py_DECREF(v);
2029 return NULL;
2030 }
Fred Drake699f3522000-06-29 21:12:41 +00002031
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002033}
2034
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002035/* POSIX methods */
2036
Guido van Rossum94f6f721999-01-06 18:42:14 +00002037
2038static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002039posix_do_stat(char *function_name, path_t *path,
2040 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002041{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002042 STRUCT_STAT st;
2043 int result;
2044
2045#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2046 if (follow_symlinks_specified(function_name, follow_symlinks))
2047 return NULL;
2048#endif
2049
2050 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2051 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2052 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2053 return NULL;
2054
2055 Py_BEGIN_ALLOW_THREADS
2056 if (path->fd != -1)
2057 result = FSTAT(path->fd, &st);
2058 else
2059#ifdef MS_WINDOWS
2060 if (path->wide) {
2061 if (follow_symlinks)
2062 result = win32_stat_w(path->wide, &st);
2063 else
2064 result = win32_lstat_w(path->wide, &st);
2065 }
2066 else
2067#endif
2068#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2069 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2070 result = LSTAT(path->narrow, &st);
2071 else
2072#endif
2073#ifdef HAVE_FSTATAT
2074 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2075 result = fstatat(dir_fd, path->narrow, &st,
2076 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2077 else
2078#endif
2079 result = STAT(path->narrow, &st);
2080 Py_END_ALLOW_THREADS
2081
Victor Stinner292c8352012-10-30 02:17:38 +01002082 if (result != 0) {
2083 return path_error(path);
2084 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002085
2086 return _pystat_fromstructstat(&st);
2087}
2088
2089PyDoc_STRVAR(posix_stat__doc__,
2090"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2091Perform a stat system call on the given path.\n\
2092\n\
2093path may be specified as either a string or as an open file descriptor.\n\
2094\n\
2095If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2096 and path should be relative; path will then be relative to that directory.\n\
2097 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2098 it will raise a NotImplementedError.\n\
2099If follow_symlinks is False, and the last element of the path is a symbolic\n\
2100 link, stat will examine the symbolic link itself instead of the file the\n\
2101 link points to.\n\
2102It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2103 an open file descriptor.");
2104
2105static PyObject *
2106posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2107{
2108 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2109 path_t path;
2110 int dir_fd = DEFAULT_DIR_FD;
2111 int follow_symlinks = 1;
2112 PyObject *return_value;
2113
2114 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002115 path.function_name = "stat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002116 path.allow_fd = 1;
2117 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2118 path_converter, &path,
2119#ifdef HAVE_FSTATAT
2120 dir_fd_converter, &dir_fd,
2121#else
2122 dir_fd_unavailable, &dir_fd,
2123#endif
2124 &follow_symlinks))
2125 return NULL;
2126 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2127 path_cleanup(&path);
2128 return return_value;
2129}
2130
2131PyDoc_STRVAR(posix_lstat__doc__,
2132"lstat(path, *, dir_fd=None) -> stat result\n\n\
2133Like stat(), but do not follow symbolic links.\n\
2134Equivalent to stat(path, follow_symlinks=False).");
2135
2136static PyObject *
2137posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2138{
2139 static char *keywords[] = {"path", "dir_fd", NULL};
2140 path_t path;
2141 int dir_fd = DEFAULT_DIR_FD;
2142 int follow_symlinks = 0;
2143 PyObject *return_value;
2144
2145 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002146 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002147 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2148 path_converter, &path,
2149#ifdef HAVE_FSTATAT
2150 dir_fd_converter, &dir_fd
2151#else
2152 dir_fd_unavailable, &dir_fd
2153#endif
2154 ))
2155 return NULL;
2156 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2157 path_cleanup(&path);
2158 return return_value;
2159}
2160
2161PyDoc_STRVAR(posix_access__doc__,
2162"access(path, mode, *, dir_fd=None, effective_ids=False,\
2163 follow_symlinks=True)\n\n\
2164Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2165False otherwise.\n\
2166\n\
2167If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2168 and path should be relative; path will then be relative to that directory.\n\
2169If effective_ids is True, access will use the effective uid/gid instead of\n\
2170 the real uid/gid.\n\
2171If follow_symlinks is False, and the last element of the path is a symbolic\n\
2172 link, access will examine the symbolic link itself instead of the file the\n\
2173 link points to.\n\
2174dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2175 on your platform. If they are unavailable, using them will raise a\n\
2176 NotImplementedError.\n\
2177\n\
2178Note that most operations will use the effective uid/gid, therefore this\n\
2179 routine can be used in a suid/sgid environment to test if the invoking user\n\
2180 has the specified access to the path.\n\
2181The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2182 of R_OK, W_OK, and X_OK.");
2183
2184static PyObject *
2185posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2186{
2187 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2188 "follow_symlinks", NULL};
2189 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002190 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002191 int dir_fd = DEFAULT_DIR_FD;
2192 int effective_ids = 0;
2193 int follow_symlinks = 1;
2194 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002195
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002196#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002197 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002198#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002199 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002200#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002201
2202 memset(&path, 0, sizeof(path));
2203 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2204 path_converter, &path, &mode,
2205#ifdef HAVE_FACCESSAT
2206 dir_fd_converter, &dir_fd,
2207#else
2208 dir_fd_unavailable, &dir_fd,
2209#endif
2210 &effective_ids, &follow_symlinks))
2211 return NULL;
2212
2213#ifndef HAVE_FACCESSAT
2214 if (follow_symlinks_specified("access", follow_symlinks))
2215 goto exit;
2216
2217 if (effective_ids) {
2218 argument_unavailable_error("access", "effective_ids");
2219 goto exit;
2220 }
2221#endif
2222
2223#ifdef MS_WINDOWS
2224 Py_BEGIN_ALLOW_THREADS
2225 if (path.wide != NULL)
2226 attr = GetFileAttributesW(path.wide);
2227 else
2228 attr = GetFileAttributesA(path.narrow);
2229 Py_END_ALLOW_THREADS
2230
2231 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002232 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002233 * * we didn't get a -1, and
2234 * * write access wasn't requested,
2235 * * or the file isn't read-only,
2236 * * or it's a directory.
2237 * (Directories cannot be read-only on Windows.)
2238 */
2239 return_value = PyBool_FromLong(
2240 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002241 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002242 !(attr & FILE_ATTRIBUTE_READONLY) ||
2243 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2244#else
2245
2246 Py_BEGIN_ALLOW_THREADS
2247#ifdef HAVE_FACCESSAT
2248 if ((dir_fd != DEFAULT_DIR_FD) ||
2249 effective_ids ||
2250 !follow_symlinks) {
2251 int flags = 0;
2252 if (!follow_symlinks)
2253 flags |= AT_SYMLINK_NOFOLLOW;
2254 if (effective_ids)
2255 flags |= AT_EACCESS;
2256 result = faccessat(dir_fd, path.narrow, mode, flags);
2257 }
2258 else
2259#endif
2260 result = access(path.narrow, mode);
2261 Py_END_ALLOW_THREADS
2262 return_value = PyBool_FromLong(!result);
2263#endif
2264
2265#ifndef HAVE_FACCESSAT
2266exit:
2267#endif
2268 path_cleanup(&path);
2269 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002270}
2271
Guido van Rossumd371ff11999-01-25 16:12:23 +00002272#ifndef F_OK
2273#define F_OK 0
2274#endif
2275#ifndef R_OK
2276#define R_OK 4
2277#endif
2278#ifndef W_OK
2279#define W_OK 2
2280#endif
2281#ifndef X_OK
2282#define X_OK 1
2283#endif
2284
2285#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002286PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002287"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002288Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002289
2290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002291posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002292{
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 int id;
2294 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002295
Victor Stinner8c62be82010-05-06 00:08:46 +00002296 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2297 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002298
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002299#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002300 /* file descriptor 0 only, the default input device (stdin) */
2301 if (id == 0) {
2302 ret = ttyname();
2303 }
2304 else {
2305 ret = NULL;
2306 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002307#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002308 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002309#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002310 if (ret == NULL)
2311 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002312 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002313}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002314#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002315
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002316#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002317PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002318"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002319Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002320
2321static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002322posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002323{
Victor Stinner8c62be82010-05-06 00:08:46 +00002324 char *ret;
2325 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002326
Greg Wardb48bc172000-03-01 21:51:56 +00002327#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002328 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002329#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002330 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002331#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002332 if (ret == NULL)
2333 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002334 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002335}
2336#endif
2337
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002338PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002339"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002340Change the current working directory to the specified path.\n\
2341\n\
2342path may always be specified as a string.\n\
2343On some platforms, path may also be specified as an open file descriptor.\n\
2344 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002345
Barry Warsaw53699e91996-12-10 23:23:01 +00002346static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002347posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002348{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002349 path_t path;
2350 int result;
2351 PyObject *return_value = NULL;
2352 static char *keywords[] = {"path", NULL};
2353
2354 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002355 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002356#ifdef HAVE_FCHDIR
2357 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002358#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002359 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2360 path_converter, &path
2361 ))
2362 return NULL;
2363
2364 Py_BEGIN_ALLOW_THREADS
2365#ifdef MS_WINDOWS
2366 if (path.wide)
2367 result = win32_wchdir(path.wide);
2368 else
2369 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002370 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002371#else
2372#ifdef HAVE_FCHDIR
2373 if (path.fd != -1)
2374 result = fchdir(path.fd);
2375 else
2376#endif
2377 result = chdir(path.narrow);
2378#endif
2379 Py_END_ALLOW_THREADS
2380
2381 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002382 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002383 goto exit;
2384 }
2385
2386 return_value = Py_None;
2387 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002388
Larry Hastings9cf065c2012-06-22 16:30:09 -07002389exit:
2390 path_cleanup(&path);
2391 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002392}
2393
Fred Drake4d1e64b2002-04-15 19:40:07 +00002394#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002395PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002396"fchdir(fd)\n\n\
2397Change to the directory of the given file descriptor. fd must be\n\
2398opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002399
2400static PyObject *
2401posix_fchdir(PyObject *self, PyObject *fdobj)
2402{
Victor Stinner8c62be82010-05-06 00:08:46 +00002403 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002404}
2405#endif /* HAVE_FCHDIR */
2406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002407
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002408PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002409"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2410Change the access permissions of a file.\n\
2411\n\
2412path may always be specified as a string.\n\
2413On some platforms, path may also be specified as an open file descriptor.\n\
2414 If this functionality is unavailable, using it raises an exception.\n\
2415If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2416 and path should be relative; path will then be relative to that directory.\n\
2417If follow_symlinks is False, and the last element of the path is a symbolic\n\
2418 link, chmod will modify the symbolic link itself instead of the file the\n\
2419 link points to.\n\
2420It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2421 an open file descriptor.\n\
2422dir_fd and follow_symlinks may not be implemented on your platform.\n\
2423 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002424
Barry Warsaw53699e91996-12-10 23:23:01 +00002425static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002426posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002427{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002428 path_t path;
2429 int mode;
2430 int dir_fd = DEFAULT_DIR_FD;
2431 int follow_symlinks = 1;
2432 int result;
2433 PyObject *return_value = NULL;
2434 static char *keywords[] = {"path", "mode", "dir_fd",
2435 "follow_symlinks", NULL};
2436
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002437#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002438 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002439#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002440
Larry Hastings9cf065c2012-06-22 16:30:09 -07002441#ifdef HAVE_FCHMODAT
2442 int fchmodat_nofollow_unsupported = 0;
2443#endif
2444
2445 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002446 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002447#ifdef HAVE_FCHMOD
2448 path.allow_fd = 1;
2449#endif
2450 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2451 path_converter, &path,
2452 &mode,
2453#ifdef HAVE_FCHMODAT
2454 dir_fd_converter, &dir_fd,
2455#else
2456 dir_fd_unavailable, &dir_fd,
2457#endif
2458 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002459 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002460
2461#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2462 if (follow_symlinks_specified("chmod", follow_symlinks))
2463 goto exit;
2464#endif
2465
2466#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002467 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002468 if (path.wide)
2469 attr = GetFileAttributesW(path.wide);
2470 else
2471 attr = GetFileAttributesA(path.narrow);
2472 if (attr == 0xFFFFFFFF)
2473 result = 0;
2474 else {
2475 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002476 attr &= ~FILE_ATTRIBUTE_READONLY;
2477 else
2478 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002479 if (path.wide)
2480 result = SetFileAttributesW(path.wide, attr);
2481 else
2482 result = SetFileAttributesA(path.narrow, attr);
2483 }
2484 Py_END_ALLOW_THREADS
2485
2486 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002487 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002488 goto exit;
2489 }
2490#else /* MS_WINDOWS */
2491 Py_BEGIN_ALLOW_THREADS
2492#ifdef HAVE_FCHMOD
2493 if (path.fd != -1)
2494 result = fchmod(path.fd, mode);
2495 else
2496#endif
2497#ifdef HAVE_LCHMOD
2498 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2499 result = lchmod(path.narrow, mode);
2500 else
2501#endif
2502#ifdef HAVE_FCHMODAT
2503 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2504 /*
2505 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2506 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002507 * and then says it isn't implemented yet.
2508 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002509 *
2510 * Once it is supported, os.chmod will automatically
2511 * support dir_fd and follow_symlinks=False. (Hopefully.)
2512 * Until then, we need to be careful what exception we raise.
2513 */
2514 result = fchmodat(dir_fd, path.narrow, mode,
2515 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2516 /*
2517 * But wait! We can't throw the exception without allowing threads,
2518 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2519 */
2520 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002521 result &&
2522 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2523 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002524 }
2525 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002526#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002527 result = chmod(path.narrow, mode);
2528 Py_END_ALLOW_THREADS
2529
2530 if (result) {
2531#ifdef HAVE_FCHMODAT
2532 if (fchmodat_nofollow_unsupported) {
2533 if (dir_fd != DEFAULT_DIR_FD)
2534 dir_fd_and_follow_symlinks_invalid("chmod",
2535 dir_fd, follow_symlinks);
2536 else
2537 follow_symlinks_specified("chmod", follow_symlinks);
2538 }
2539 else
2540#endif
Victor Stinner292c8352012-10-30 02:17:38 +01002541 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002542 goto exit;
2543 }
2544#endif
2545
2546 Py_INCREF(Py_None);
2547 return_value = Py_None;
2548exit:
2549 path_cleanup(&path);
2550 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002551}
2552
Larry Hastings9cf065c2012-06-22 16:30:09 -07002553
Christian Heimes4e30a842007-11-30 22:12:06 +00002554#ifdef HAVE_FCHMOD
2555PyDoc_STRVAR(posix_fchmod__doc__,
2556"fchmod(fd, mode)\n\n\
2557Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002558descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002559
2560static PyObject *
2561posix_fchmod(PyObject *self, PyObject *args)
2562{
Victor Stinner8c62be82010-05-06 00:08:46 +00002563 int fd, mode, res;
2564 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2565 return NULL;
2566 Py_BEGIN_ALLOW_THREADS
2567 res = fchmod(fd, mode);
2568 Py_END_ALLOW_THREADS
2569 if (res < 0)
2570 return posix_error();
2571 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002572}
2573#endif /* HAVE_FCHMOD */
2574
2575#ifdef HAVE_LCHMOD
2576PyDoc_STRVAR(posix_lchmod__doc__,
2577"lchmod(path, mode)\n\n\
2578Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002579affects the link itself rather than the target.\n\
2580Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002581
2582static PyObject *
2583posix_lchmod(PyObject *self, PyObject *args)
2584{
Victor Stinner292c8352012-10-30 02:17:38 +01002585 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002586 int i;
2587 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002588 memset(&path, 0, sizeof(path));
2589 path.function_name = "lchmod";
2590 if (!PyArg_ParseTuple(args, "O&i:lchmod",
2591 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002592 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002593 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002594 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002596 if (res < 0) {
2597 path_error(&path);
2598 path_cleanup(&path);
2599 return NULL;
2600 }
2601 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002602 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002603}
2604#endif /* HAVE_LCHMOD */
2605
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002606
Thomas Wouterscf297e42007-02-23 15:07:44 +00002607#ifdef HAVE_CHFLAGS
2608PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002609"chflags(path, flags, *, follow_symlinks=True)\n\n\
2610Set file flags.\n\
2611\n\
2612If follow_symlinks is False, and the last element of the path is a symbolic\n\
2613 link, chflags will change flags on the symbolic link itself instead of the\n\
2614 file the link points to.\n\
2615follow_symlinks may not be implemented on your platform. If it is\n\
2616unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002617
2618static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002620{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002622 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623 int follow_symlinks = 1;
2624 int result;
2625 PyObject *return_value;
2626 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2627
2628 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002629 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002630 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2631 path_converter, &path,
2632 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002633 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002634
2635#ifndef HAVE_LCHFLAGS
2636 if (follow_symlinks_specified("chflags", follow_symlinks))
2637 goto exit;
2638#endif
2639
Victor Stinner8c62be82010-05-06 00:08:46 +00002640 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002641#ifdef HAVE_LCHFLAGS
2642 if (!follow_symlinks)
2643 result = lchflags(path.narrow, flags);
2644 else
2645#endif
2646 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002647 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002648
2649 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002650 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002651 goto exit;
2652 }
2653
2654 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002655 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002656
2657exit:
2658 path_cleanup(&path);
2659 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002660}
2661#endif /* HAVE_CHFLAGS */
2662
2663#ifdef HAVE_LCHFLAGS
2664PyDoc_STRVAR(posix_lchflags__doc__,
2665"lchflags(path, flags)\n\n\
2666Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002667This function will not follow symbolic links.\n\
2668Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002669
2670static PyObject *
2671posix_lchflags(PyObject *self, PyObject *args)
2672{
Victor Stinner292c8352012-10-30 02:17:38 +01002673 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002674 unsigned long flags;
2675 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002676 memset(&path, 0, sizeof(path));
2677 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00002678 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01002679 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00002680 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002681 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002682 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002684 if (res < 0) {
2685 path_error(&path);
2686 path_cleanup(&path);
2687 return NULL;
2688 }
2689 path_cleanup(&path);
2690 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002691}
2692#endif /* HAVE_LCHFLAGS */
2693
Martin v. Löwis244edc82001-10-04 22:44:26 +00002694#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002695PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002696"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002697Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002698
2699static PyObject *
2700posix_chroot(PyObject *self, PyObject *args)
2701{
Victor Stinner292c8352012-10-30 02:17:38 +01002702 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002703}
2704#endif
2705
Guido van Rossum21142a01999-01-08 21:05:37 +00002706#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002707PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002708"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002709force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002710
2711static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002712posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002713{
Stefan Krah0e803b32010-11-26 16:16:47 +00002714 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002715}
2716#endif /* HAVE_FSYNC */
2717
Ross Lagerwall7807c352011-03-17 20:20:30 +02002718#ifdef HAVE_SYNC
2719PyDoc_STRVAR(posix_sync__doc__,
2720"sync()\n\n\
2721Force write of everything to disk.");
2722
2723static PyObject *
2724posix_sync(PyObject *self, PyObject *noargs)
2725{
2726 Py_BEGIN_ALLOW_THREADS
2727 sync();
2728 Py_END_ALLOW_THREADS
2729 Py_RETURN_NONE;
2730}
2731#endif
2732
Guido van Rossum21142a01999-01-08 21:05:37 +00002733#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002734
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002735#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002736extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2737#endif
2738
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002739PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002740"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002741force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002742 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002743
2744static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002745posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002746{
Stefan Krah0e803b32010-11-26 16:16:47 +00002747 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002748}
2749#endif /* HAVE_FDATASYNC */
2750
2751
Fredrik Lundh10723342000-07-10 16:38:09 +00002752#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002753PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002754"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2755Change the owner and group id of path to the numeric uid and gid.\n\
2756\n\
2757path may always be specified as a string.\n\
2758On some platforms, path may also be specified as an open file descriptor.\n\
2759 If this functionality is unavailable, using it raises an exception.\n\
2760If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2761 and path should be relative; path will then be relative to that directory.\n\
2762If follow_symlinks is False, and the last element of the path is a symbolic\n\
2763 link, chown will modify the symbolic link itself instead of the file the\n\
2764 link points to.\n\
2765It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2766 an open file descriptor.\n\
2767dir_fd and follow_symlinks may not be implemented on your platform.\n\
2768 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002769
Barry Warsaw53699e91996-12-10 23:23:01 +00002770static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002771posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002772{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002773 path_t path;
2774 long uid_l, gid_l;
2775 uid_t uid;
2776 gid_t gid;
2777 int dir_fd = DEFAULT_DIR_FD;
2778 int follow_symlinks = 1;
2779 int result;
2780 PyObject *return_value = NULL;
2781 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2782 "follow_symlinks", NULL};
2783
2784 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002785 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002786#ifdef HAVE_FCHOWN
2787 path.allow_fd = 1;
2788#endif
2789 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2790 path_converter, &path,
2791 &uid_l, &gid_l,
2792#ifdef HAVE_FCHOWNAT
2793 dir_fd_converter, &dir_fd,
2794#else
2795 dir_fd_unavailable, &dir_fd,
2796#endif
2797 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002798 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799
2800#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2801 if (follow_symlinks_specified("chown", follow_symlinks))
2802 goto exit;
2803#endif
2804 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2805 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2806 goto exit;
2807
2808#ifdef __APPLE__
2809 /*
2810 * This is for Mac OS X 10.3, which doesn't have lchown.
2811 * (But we still have an lchown symbol because of weak-linking.)
2812 * It doesn't have fchownat either. So there's no possibility
2813 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02002814 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002815 if ((!follow_symlinks) && (lchown == NULL)) {
2816 follow_symlinks_specified("chown", follow_symlinks);
2817 goto exit;
2818 }
2819#endif
2820
Victor Stinner8c62be82010-05-06 00:08:46 +00002821 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822 uid = (uid_t)uid_l;
2823 gid = (uid_t)gid_l;
2824#ifdef HAVE_FCHOWN
2825 if (path.fd != -1)
2826 result = fchown(path.fd, uid, gid);
2827 else
2828#endif
2829#ifdef HAVE_LCHOWN
2830 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2831 result = lchown(path.narrow, uid, gid);
2832 else
2833#endif
2834#ifdef HAVE_FCHOWNAT
2835 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
2836 result = fchownat(dir_fd, path.narrow, uid, gid,
2837 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2838 else
2839#endif
2840 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002841 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002842
2843 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002844 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002845 goto exit;
2846 }
2847
2848 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002849 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002850
2851exit:
2852 path_cleanup(&path);
2853 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002854}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002855#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002856
Christian Heimes4e30a842007-11-30 22:12:06 +00002857#ifdef HAVE_FCHOWN
2858PyDoc_STRVAR(posix_fchown__doc__,
2859"fchown(fd, uid, gid)\n\n\
2860Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002861fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002862
2863static PyObject *
2864posix_fchown(PyObject *self, PyObject *args)
2865{
Victor Stinner8c62be82010-05-06 00:08:46 +00002866 int fd;
2867 long uid, gid;
2868 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002869 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002870 return NULL;
2871 Py_BEGIN_ALLOW_THREADS
2872 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2873 Py_END_ALLOW_THREADS
2874 if (res < 0)
2875 return posix_error();
2876 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002877}
2878#endif /* HAVE_FCHOWN */
2879
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002880#ifdef HAVE_LCHOWN
2881PyDoc_STRVAR(posix_lchown__doc__,
2882"lchown(path, uid, gid)\n\n\
2883Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002884This function will not follow symbolic links.\n\
2885Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002886
2887static PyObject *
2888posix_lchown(PyObject *self, PyObject *args)
2889{
Victor Stinner292c8352012-10-30 02:17:38 +01002890 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002891 long uid, gid;
2892 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002893 memset(&path, 0, sizeof(path));
2894 path.function_name = "lchown";
Victor Stinner8c62be82010-05-06 00:08:46 +00002895 if (!PyArg_ParseTuple(args, "O&ll:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01002896 path_converter, &path,
Victor Stinner8c62be82010-05-06 00:08:46 +00002897 &uid, &gid))
2898 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002900 res = lchown(path.narrow, (uid_t) uid, (gid_t) gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002901 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002902 if (res < 0) {
2903 path_error(&path);
2904 path_cleanup(&path);
2905 return NULL;
2906 }
2907 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002908 Py_INCREF(Py_None);
2909 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002910}
2911#endif /* HAVE_LCHOWN */
2912
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002913
Guido van Rossum36bc6801995-06-14 22:54:23 +00002914#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002915static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002916posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002917{
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 char buf[1026];
2919 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002920
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002921#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002922 if (!use_bytes) {
2923 wchar_t wbuf[1026];
2924 wchar_t *wbuf2 = wbuf;
2925 PyObject *resobj;
2926 DWORD len;
2927 Py_BEGIN_ALLOW_THREADS
2928 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2929 /* If the buffer is large enough, len does not include the
2930 terminating \0. If the buffer is too small, len includes
2931 the space needed for the terminator. */
2932 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2933 wbuf2 = malloc(len * sizeof(wchar_t));
2934 if (wbuf2)
2935 len = GetCurrentDirectoryW(len, wbuf2);
2936 }
2937 Py_END_ALLOW_THREADS
2938 if (!wbuf2) {
2939 PyErr_NoMemory();
2940 return NULL;
2941 }
2942 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002943 if (wbuf2 != wbuf)
2944 free(wbuf2);
2945 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00002946 }
2947 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01002948 if (wbuf2 != wbuf)
2949 free(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00002950 return resobj;
2951 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01002952
2953 if (win32_warn_bytes_api())
2954 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002955#endif
2956
Victor Stinner8c62be82010-05-06 00:08:46 +00002957 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002958 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00002959 Py_END_ALLOW_THREADS
2960 if (res == NULL)
2961 return posix_error();
2962 if (use_bytes)
2963 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002964 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002965}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002966
2967PyDoc_STRVAR(posix_getcwd__doc__,
2968"getcwd() -> path\n\n\
2969Return a unicode string representing the current working directory.");
2970
2971static PyObject *
2972posix_getcwd_unicode(PyObject *self)
2973{
2974 return posix_getcwd(0);
2975}
2976
2977PyDoc_STRVAR(posix_getcwdb__doc__,
2978"getcwdb() -> path\n\n\
2979Return a bytes string representing the current working directory.");
2980
2981static PyObject *
2982posix_getcwd_bytes(PyObject *self)
2983{
2984 return posix_getcwd(1);
2985}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002986#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002987
Larry Hastings9cf065c2012-06-22 16:30:09 -07002988#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
2989#define HAVE_LINK 1
2990#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002991
Guido van Rossumb6775db1994-08-01 11:34:53 +00002992#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002993PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
2995Create a hard link to a file.\n\
2996\n\
2997If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
2998 descriptor open to a directory, and the respective path string (src or dst)\n\
2999 should be relative; the path will then be relative to that directory.\n\
3000If follow_symlinks is False, and the last element of src is a symbolic\n\
3001 link, link will create a link to the symbolic link itself instead of the\n\
3002 file the link points to.\n\
3003src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3004 platform. If they are unavailable, using them will raise a\n\
3005 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003006
Barry Warsaw53699e91996-12-10 23:23:01 +00003007static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003008posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003009{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010 path_t src, dst;
3011 int src_dir_fd = DEFAULT_DIR_FD;
3012 int dst_dir_fd = DEFAULT_DIR_FD;
3013 int follow_symlinks = 1;
3014 PyObject *return_value = NULL;
3015 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3016 "follow_symlinks", NULL};
3017#ifdef MS_WINDOWS
3018 BOOL result;
3019#else
3020 int result;
3021#endif
3022
3023 memset(&src, 0, sizeof(src));
3024 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003025 src.function_name = "link";
3026 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003027 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3028 path_converter, &src,
3029 path_converter, &dst,
3030 dir_fd_converter, &src_dir_fd,
3031 dir_fd_converter, &dst_dir_fd,
3032 &follow_symlinks))
3033 return NULL;
3034
3035#ifndef HAVE_LINKAT
3036 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3037 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3038 goto exit;
3039 }
3040#endif
3041
3042 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3043 PyErr_SetString(PyExc_NotImplementedError,
3044 "link: src and dst must be the same type");
3045 goto exit;
3046 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003047
Brian Curtin1b9df392010-11-24 20:24:31 +00003048#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003049 Py_BEGIN_ALLOW_THREADS
3050 if (src.wide)
3051 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3052 else
3053 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3054 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003055
Larry Hastings9cf065c2012-06-22 16:30:09 -07003056 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003057 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003058 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003059 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003060#else
3061 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003062#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003063 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3064 (dst_dir_fd != DEFAULT_DIR_FD) ||
3065 (!follow_symlinks))
3066 result = linkat(src_dir_fd, src.narrow,
3067 dst_dir_fd, dst.narrow,
3068 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3069 else
3070#endif
3071 result = link(src.narrow, dst.narrow);
3072 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003073
Larry Hastings9cf065c2012-06-22 16:30:09 -07003074 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003075 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003076 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003077 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003078#endif
3079
3080 return_value = Py_None;
3081 Py_INCREF(Py_None);
3082
3083exit:
3084 path_cleanup(&src);
3085 path_cleanup(&dst);
3086 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003087}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003088#endif
3089
Brian Curtin1b9df392010-11-24 20:24:31 +00003090
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003091
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003092PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003093"listdir(path='.') -> list_of_filenames\n\n\
3094Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003095The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003096entries '.' and '..' even if they are present in the directory.\n\
3097\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003098path can be specified as either str or bytes. If path is bytes,\n\
3099 the filenames returned will also be bytes; in all other circumstances\n\
3100 the filenames returned will be str.\n\
3101On some platforms, path may also be specified as an open file descriptor;\n\
3102 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003103 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003104
Barry Warsaw53699e91996-12-10 23:23:01 +00003105static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003106posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003107{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003108 path_t path;
3109 PyObject *list = NULL;
3110 static char *keywords[] = {"path", NULL};
3111 int fd = -1;
3112
3113#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3114 PyObject *v;
3115 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3116 BOOL result;
3117 WIN32_FIND_DATA FileData;
3118 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3119 char *bufptr = namebuf;
3120 /* only claim to have space for MAX_PATH */
3121 Py_ssize_t len = sizeof(namebuf)-5;
3122 PyObject *po = NULL;
3123 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124#else
3125 PyObject *v;
3126 DIR *dirp = NULL;
3127 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003128 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003129#endif
3130
3131 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003132 path.function_name = "listdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003133 path.nullable = 1;
3134#ifdef HAVE_FDOPENDIR
3135 path.allow_fd = 1;
3136 path.fd = -1;
3137#endif
3138 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3139 path_converter, &path
3140 ))
3141 return NULL;
3142
Victor Stinner8c62be82010-05-06 00:08:46 +00003143 /* XXX Should redo this putting the (now four) versions of opendir
3144 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003145#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003146 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003147 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003148 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003149
Larry Hastings9cf065c2012-06-22 16:30:09 -07003150 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003151 po_wchars = L".";
3152 len = 1;
3153 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003154 po_wchars = path.wide;
3155 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003156 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003158 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3159 if (!wnamebuf) {
3160 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003161 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003162 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003163 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003164 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003165 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003166 if (wch != L'/' && wch != L'\\' && wch != L':')
3167 wnamebuf[len++] = L'\\';
3168 wcscpy(wnamebuf + len, L"*.*");
3169 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003170 if ((list = PyList_New(0)) == NULL) {
3171 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003172 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003173 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003174 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003175 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 if (hFindFile == INVALID_HANDLE_VALUE) {
3177 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003178 if (error == ERROR_FILE_NOT_FOUND)
3179 goto exit;
3180 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003181 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003182 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003183 }
3184 do {
3185 /* Skip over . and .. */
3186 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3187 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003188 v = PyUnicode_FromWideChar(wFileData.cFileName,
3189 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003190 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003191 Py_DECREF(list);
3192 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003193 break;
3194 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003195 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003196 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197 Py_DECREF(list);
3198 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003199 break;
3200 }
3201 Py_DECREF(v);
3202 }
3203 Py_BEGIN_ALLOW_THREADS
3204 result = FindNextFileW(hFindFile, &wFileData);
3205 Py_END_ALLOW_THREADS
3206 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3207 it got to the end of the directory. */
3208 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003209 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003210 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003211 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003212 }
3213 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003214
Larry Hastings9cf065c2012-06-22 16:30:09 -07003215 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003216 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003217 strcpy(namebuf, path.narrow);
3218 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003219 if (len > 0) {
3220 char ch = namebuf[len-1];
3221 if (ch != SEP && ch != ALTSEP && ch != ':')
3222 namebuf[len++] = '/';
3223 strcpy(namebuf + len, "*.*");
3224 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003225
Larry Hastings9cf065c2012-06-22 16:30:09 -07003226 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003227 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003228
Antoine Pitroub73caab2010-08-09 23:39:31 +00003229 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003231 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 if (hFindFile == INVALID_HANDLE_VALUE) {
3233 int error = GetLastError();
3234 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235 goto exit;
3236 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003237 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003238 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 }
3240 do {
3241 /* Skip over . and .. */
3242 if (strcmp(FileData.cFileName, ".") != 0 &&
3243 strcmp(FileData.cFileName, "..") != 0) {
3244 v = PyBytes_FromString(FileData.cFileName);
3245 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003246 Py_DECREF(list);
3247 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003248 break;
3249 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003251 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003252 Py_DECREF(list);
3253 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003254 break;
3255 }
3256 Py_DECREF(v);
3257 }
3258 Py_BEGIN_ALLOW_THREADS
3259 result = FindNextFile(hFindFile, &FileData);
3260 Py_END_ALLOW_THREADS
3261 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3262 it got to the end of the directory. */
3263 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003264 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003265 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003266 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003267 }
3268 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003269
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270exit:
3271 if (hFindFile != INVALID_HANDLE_VALUE) {
3272 if (FindClose(hFindFile) == FALSE) {
3273 if (list != NULL) {
3274 Py_DECREF(list);
Victor Stinnerb024e842012-10-31 22:24:06 +01003275 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003276 }
3277 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003278 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003279 if (wnamebuf)
3280 free(wnamebuf);
3281 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003282
Larry Hastings9cf065c2012-06-22 16:30:09 -07003283 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003284
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003285#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003286
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003288#ifdef HAVE_FDOPENDIR
3289 if (path.fd != -1) {
3290 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003291 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003292 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003293 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003294
3295 if (fd == -1) {
3296 list = posix_error();
3297 goto exit;
3298 }
3299
Larry Hastingsfdaea062012-06-25 04:42:23 -07003300 return_str = 1;
3301
Larry Hastings9cf065c2012-06-22 16:30:09 -07003302 Py_BEGIN_ALLOW_THREADS
3303 dirp = fdopendir(fd);
3304 Py_END_ALLOW_THREADS
3305 }
3306 else
3307#endif
3308 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003309 char *name;
3310 if (path.narrow) {
3311 name = path.narrow;
3312 /* only return bytes if they specified a bytes object */
3313 return_str = !(PyBytes_Check(path.object));
3314 }
3315 else {
3316 name = ".";
3317 return_str = 1;
3318 }
3319
Larry Hastings9cf065c2012-06-22 16:30:09 -07003320 Py_BEGIN_ALLOW_THREADS
3321 dirp = opendir(name);
3322 Py_END_ALLOW_THREADS
3323 }
3324
3325 if (dirp == NULL) {
Victor Stinner292c8352012-10-30 02:17:38 +01003326 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003327 goto exit;
3328 }
3329 if ((list = PyList_New(0)) == NULL) {
3330 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003331 }
3332 for (;;) {
3333 errno = 0;
3334 Py_BEGIN_ALLOW_THREADS
3335 ep = readdir(dirp);
3336 Py_END_ALLOW_THREADS
3337 if (ep == NULL) {
3338 if (errno == 0) {
3339 break;
3340 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003341 Py_DECREF(list);
Victor Stinner292c8352012-10-30 02:17:38 +01003342 list = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003343 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003344 }
3345 }
3346 if (ep->d_name[0] == '.' &&
3347 (NAMLEN(ep) == 1 ||
3348 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3349 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003350 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003351 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3352 else
3353 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003355 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 break;
3357 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003358 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003359 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003360 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003361 break;
3362 }
3363 Py_DECREF(v);
3364 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003365
Larry Hastings9cf065c2012-06-22 16:30:09 -07003366exit:
3367 if (dirp != NULL) {
3368 Py_BEGIN_ALLOW_THREADS
3369 if (fd > -1)
3370 rewinddir(dirp);
3371 closedir(dirp);
3372 Py_END_ALLOW_THREADS
3373 }
3374
3375 path_cleanup(&path);
3376
3377 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003378
Tim Peters0bb44a42000-09-15 07:44:49 +00003379#endif /* which OS */
3380} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003381
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003382#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003383/* A helper function for abspath on win32 */
3384static PyObject *
3385posix__getfullpathname(PyObject *self, PyObject *args)
3386{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003387 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003388 char outbuf[MAX_PATH*2];
3389 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003390 PyObject *po;
3391
3392 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3393 {
3394 wchar_t *wpath;
3395 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3396 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003397 DWORD result;
3398 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003399
3400 wpath = PyUnicode_AsUnicode(po);
3401 if (wpath == NULL)
3402 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003403 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003404 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003405 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003406 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003407 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003408 if (!woutbufp)
3409 return PyErr_NoMemory();
3410 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3411 }
3412 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003413 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003414 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003415 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 if (woutbufp != woutbuf)
3417 free(woutbufp);
3418 return v;
3419 }
3420 /* Drop the argument parsing error as narrow strings
3421 are also valid. */
3422 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003423
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003424 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3425 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003427 if (win32_warn_bytes_api())
3428 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003429 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003430 outbuf, &temp)) {
3431 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 return NULL;
3433 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003434 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3435 return PyUnicode_Decode(outbuf, strlen(outbuf),
3436 Py_FileSystemDefaultEncoding, NULL);
3437 }
3438 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003439} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003440
Brian Curtind25aef52011-06-13 15:16:04 -05003441
Brian Curtinf5e76d02010-11-24 13:14:05 +00003442
Brian Curtind40e6f72010-07-08 21:39:08 +00003443/* A helper function for samepath on windows */
3444static PyObject *
3445posix__getfinalpathname(PyObject *self, PyObject *args)
3446{
3447 HANDLE hFile;
3448 int buf_size;
3449 wchar_t *target_path;
3450 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003451 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003452 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003453
Victor Stinnereb5657a2011-09-30 01:44:27 +02003454 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003455 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003456 path = PyUnicode_AsUnicode(po);
3457 if (path == NULL)
3458 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003459
3460 if(!check_GetFinalPathNameByHandle()) {
3461 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3462 NotImplementedError. */
3463 return PyErr_Format(PyExc_NotImplementedError,
3464 "GetFinalPathNameByHandle not available on this platform");
3465 }
3466
3467 hFile = CreateFileW(
3468 path,
3469 0, /* desired access */
3470 0, /* share mode */
3471 NULL, /* security attributes */
3472 OPEN_EXISTING,
3473 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3474 FILE_FLAG_BACKUP_SEMANTICS,
3475 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003476
Victor Stinnereb5657a2011-09-30 01:44:27 +02003477 if(hFile == INVALID_HANDLE_VALUE)
3478 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003479
3480 /* We have a good handle to the target, use it to determine the
3481 target path name. */
3482 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3483
3484 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003485 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003486
3487 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3488 if(!target_path)
3489 return PyErr_NoMemory();
3490
3491 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3492 buf_size, VOLUME_NAME_DOS);
3493 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003494 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003495
3496 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003497 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003498
3499 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003500 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003501 free(target_path);
3502 return result;
3503
3504} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003505
3506static PyObject *
3507posix__getfileinformation(PyObject *self, PyObject *args)
3508{
3509 HANDLE hFile;
3510 BY_HANDLE_FILE_INFORMATION info;
3511 int fd;
3512
3513 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3514 return NULL;
3515
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003516 if (!_PyVerify_fd(fd))
3517 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003518
3519 hFile = (HANDLE)_get_osfhandle(fd);
3520 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003521 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003522
3523 if (!GetFileInformationByHandle(hFile, &info))
Victor Stinnerb024e842012-10-31 22:24:06 +01003524 return PyErr_SetFromWindowsErr(0);
Brian Curtin62857742010-09-06 17:07:27 +00003525
3526 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3527 info.nFileIndexHigh,
3528 info.nFileIndexLow);
3529}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003530
Brian Curtin95d028f2011-06-09 09:10:38 -05003531PyDoc_STRVAR(posix__isdir__doc__,
3532"Return true if the pathname refers to an existing directory.");
3533
Brian Curtin9c669cc2011-06-08 18:17:18 -05003534static PyObject *
3535posix__isdir(PyObject *self, PyObject *args)
3536{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003537 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003538 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003539 DWORD attributes;
3540
3541 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003542 wchar_t *wpath = PyUnicode_AsUnicode(po);
3543 if (wpath == NULL)
3544 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003545
3546 attributes = GetFileAttributesW(wpath);
3547 if (attributes == INVALID_FILE_ATTRIBUTES)
3548 Py_RETURN_FALSE;
3549 goto check;
3550 }
3551 /* Drop the argument parsing error as narrow strings
3552 are also valid. */
3553 PyErr_Clear();
3554
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003555 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003556 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003557 if (win32_warn_bytes_api())
3558 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003559 attributes = GetFileAttributesA(path);
3560 if (attributes == INVALID_FILE_ATTRIBUTES)
3561 Py_RETURN_FALSE;
3562
3563check:
3564 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3565 Py_RETURN_TRUE;
3566 else
3567 Py_RETURN_FALSE;
3568}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003569#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003570
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003571PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3573Create a directory.\n\
3574\n\
3575If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3576 and path should be relative; path will then be relative to that directory.\n\
3577dir_fd may not be implemented on your platform.\n\
3578 If it is unavailable, using it will raise a NotImplementedError.\n\
3579\n\
3580The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003581
Barry Warsaw53699e91996-12-10 23:23:01 +00003582static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003583posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003584{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003586 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 int dir_fd = DEFAULT_DIR_FD;
3588 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3589 PyObject *return_value = NULL;
3590 int result;
3591
3592 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003593 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3595 path_converter, &path, &mode,
3596#ifdef HAVE_MKDIRAT
3597 dir_fd_converter, &dir_fd
3598#else
3599 dir_fd_unavailable, &dir_fd
3600#endif
3601 ))
3602 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003603
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003604#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 if (path.wide)
3607 result = CreateDirectoryW(path.wide, NULL);
3608 else
3609 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003610 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003611
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003613 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003614 goto exit;
3615 }
3616#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618#if HAVE_MKDIRAT
3619 if (dir_fd != DEFAULT_DIR_FD)
3620 result = mkdirat(dir_fd, path.narrow, mode);
3621 else
3622#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003623#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003624 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003625#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003627#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01003630 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003631 goto exit;
3632 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003633#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 return_value = Py_None;
3635 Py_INCREF(Py_None);
3636exit:
3637 path_cleanup(&path);
3638 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003639}
3640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003641
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003642/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3643#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003644#include <sys/resource.h>
3645#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003646
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003647
3648#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003649PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003650"nice(inc) -> new_priority\n\n\
3651Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003652
Barry Warsaw53699e91996-12-10 23:23:01 +00003653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003654posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003655{
Victor Stinner8c62be82010-05-06 00:08:46 +00003656 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003657
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3659 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003660
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 /* There are two flavours of 'nice': one that returns the new
3662 priority (as required by almost all standards out there) and the
3663 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3664 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003665
Victor Stinner8c62be82010-05-06 00:08:46 +00003666 If we are of the nice family that returns the new priority, we
3667 need to clear errno before the call, and check if errno is filled
3668 before calling posix_error() on a returnvalue of -1, because the
3669 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003670
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 errno = 0;
3672 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003673#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003674 if (value == 0)
3675 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003676#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 if (value == -1 && errno != 0)
3678 /* either nice() or getpriority() returned an error */
3679 return posix_error();
3680 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003681}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003682#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003683
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003684
3685#ifdef HAVE_GETPRIORITY
3686PyDoc_STRVAR(posix_getpriority__doc__,
3687"getpriority(which, who) -> current_priority\n\n\
3688Get program scheduling priority.");
3689
3690static PyObject *
3691posix_getpriority(PyObject *self, PyObject *args)
3692{
3693 int which, who, retval;
3694
3695 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3696 return NULL;
3697 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003698 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003699 if (errno != 0)
3700 return posix_error();
3701 return PyLong_FromLong((long)retval);
3702}
3703#endif /* HAVE_GETPRIORITY */
3704
3705
3706#ifdef HAVE_SETPRIORITY
3707PyDoc_STRVAR(posix_setpriority__doc__,
3708"setpriority(which, who, prio) -> None\n\n\
3709Set program scheduling priority.");
3710
3711static PyObject *
3712posix_setpriority(PyObject *self, PyObject *args)
3713{
3714 int which, who, prio, retval;
3715
3716 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3717 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003718 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003719 if (retval == -1)
3720 return posix_error();
3721 Py_RETURN_NONE;
3722}
3723#endif /* HAVE_SETPRIORITY */
3724
3725
Barry Warsaw53699e91996-12-10 23:23:01 +00003726static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003727internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003728{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003729 char *function_name = is_replace ? "replace" : "rename";
3730 path_t src;
3731 path_t dst;
3732 int src_dir_fd = DEFAULT_DIR_FD;
3733 int dst_dir_fd = DEFAULT_DIR_FD;
3734 int dir_fd_specified;
3735 PyObject *return_value = NULL;
3736 char format[24];
3737 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3738
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003739#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003740 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003741 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003742#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003743 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003744#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003745
3746 memset(&src, 0, sizeof(src));
3747 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003748 src.function_name = function_name;
3749 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003750 strcpy(format, "O&O&|$O&O&:");
3751 strcat(format, function_name);
3752 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3753 path_converter, &src,
3754 path_converter, &dst,
3755 dir_fd_converter, &src_dir_fd,
3756 dir_fd_converter, &dst_dir_fd))
3757 return NULL;
3758
3759 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3760 (dst_dir_fd != DEFAULT_DIR_FD);
3761#ifndef HAVE_RENAMEAT
3762 if (dir_fd_specified) {
3763 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
3764 goto exit;
3765 }
3766#endif
3767
3768 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3769 PyErr_Format(PyExc_ValueError,
3770 "%s: src and dst must be the same type", function_name);
3771 goto exit;
3772 }
3773
3774#ifdef MS_WINDOWS
3775 Py_BEGIN_ALLOW_THREADS
3776 if (src.wide)
3777 result = MoveFileExW(src.wide, dst.wide, flags);
3778 else
3779 result = MoveFileExA(src.narrow, dst.narrow, flags);
3780 Py_END_ALLOW_THREADS
3781
3782 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003783 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003784 goto exit;
3785 }
3786
3787#else
3788 Py_BEGIN_ALLOW_THREADS
3789#ifdef HAVE_RENAMEAT
3790 if (dir_fd_specified)
3791 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
3792 else
3793#endif
3794 result = rename(src.narrow, dst.narrow);
3795 Py_END_ALLOW_THREADS
3796
3797 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003798 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003799 goto exit;
3800 }
3801#endif
3802
3803 Py_INCREF(Py_None);
3804 return_value = Py_None;
3805exit:
3806 path_cleanup(&src);
3807 path_cleanup(&dst);
3808 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003809}
3810
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003811PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003812"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3813Rename a file or directory.\n\
3814\n\
3815If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3816 descriptor open to a directory, and the respective path string (src or dst)\n\
3817 should be relative; the path will then be relative to that directory.\n\
3818src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3819 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003820
3821static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003822posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003823{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003824 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003825}
3826
3827PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003828"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3829Rename a file or directory, overwriting the destination.\n\
3830\n\
3831If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3832 descriptor open to a directory, and the respective path string (src or dst)\n\
3833 should be relative; the path will then be relative to that directory.\n\
3834src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3835 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003836
3837static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003838posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003839{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003840 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003841}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003842
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003843PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003844"rmdir(path, *, dir_fd=None)\n\n\
3845Remove a directory.\n\
3846\n\
3847If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3848 and path should be relative; path will then be relative to that directory.\n\
3849dir_fd may not be implemented on your platform.\n\
3850 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003851
Barry Warsaw53699e91996-12-10 23:23:01 +00003852static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003853posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003854{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003855 path_t path;
3856 int dir_fd = DEFAULT_DIR_FD;
3857 static char *keywords[] = {"path", "dir_fd", NULL};
3858 int result;
3859 PyObject *return_value = NULL;
3860
3861 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003862 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003863 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
3864 path_converter, &path,
3865#ifdef HAVE_UNLINKAT
3866 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003867#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003868 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003869#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003870 ))
3871 return NULL;
3872
3873 Py_BEGIN_ALLOW_THREADS
3874#ifdef MS_WINDOWS
3875 if (path.wide)
3876 result = RemoveDirectoryW(path.wide);
3877 else
3878 result = RemoveDirectoryA(path.narrow);
3879 result = !result; /* Windows, success=1, UNIX, success=0 */
3880#else
3881#ifdef HAVE_UNLINKAT
3882 if (dir_fd != DEFAULT_DIR_FD)
3883 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
3884 else
3885#endif
3886 result = rmdir(path.narrow);
3887#endif
3888 Py_END_ALLOW_THREADS
3889
3890 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003891 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003892 goto exit;
3893 }
3894
3895 return_value = Py_None;
3896 Py_INCREF(Py_None);
3897
3898exit:
3899 path_cleanup(&path);
3900 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003901}
3902
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003903
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003904#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003905PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003906"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003907Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003908
Barry Warsaw53699e91996-12-10 23:23:01 +00003909static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003910posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003911{
Victor Stinner8c62be82010-05-06 00:08:46 +00003912 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003913#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003914 wchar_t *command;
3915 if (!PyArg_ParseTuple(args, "u:system", &command))
3916 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003917
Victor Stinner8c62be82010-05-06 00:08:46 +00003918 Py_BEGIN_ALLOW_THREADS
3919 sts = _wsystem(command);
3920 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003921#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 PyObject *command_obj;
3923 char *command;
3924 if (!PyArg_ParseTuple(args, "O&:system",
3925 PyUnicode_FSConverter, &command_obj))
3926 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003927
Victor Stinner8c62be82010-05-06 00:08:46 +00003928 command = PyBytes_AsString(command_obj);
3929 Py_BEGIN_ALLOW_THREADS
3930 sts = system(command);
3931 Py_END_ALLOW_THREADS
3932 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003933#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003934 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003935}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003936#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003937
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003938
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003939PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003940"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003941Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003942
Barry Warsaw53699e91996-12-10 23:23:01 +00003943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003944posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003945{
Victor Stinner8c62be82010-05-06 00:08:46 +00003946 int i;
3947 if (!PyArg_ParseTuple(args, "i:umask", &i))
3948 return NULL;
3949 i = (int)umask(i);
3950 if (i < 0)
3951 return posix_error();
3952 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003953}
3954
Brian Curtind40e6f72010-07-08 21:39:08 +00003955#ifdef MS_WINDOWS
3956
3957/* override the default DeleteFileW behavior so that directory
3958symlinks can be removed with this function, the same as with
3959Unix symlinks */
3960BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3961{
3962 WIN32_FILE_ATTRIBUTE_DATA info;
3963 WIN32_FIND_DATAW find_data;
3964 HANDLE find_data_handle;
3965 int is_directory = 0;
3966 int is_link = 0;
3967
3968 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3969 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003970
Brian Curtind40e6f72010-07-08 21:39:08 +00003971 /* Get WIN32_FIND_DATA structure for the path to determine if
3972 it is a symlink */
3973 if(is_directory &&
3974 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3975 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3976
3977 if(find_data_handle != INVALID_HANDLE_VALUE) {
3978 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3979 FindClose(find_data_handle);
3980 }
3981 }
3982 }
3983
3984 if (is_directory && is_link)
3985 return RemoveDirectoryW(lpFileName);
3986
3987 return DeleteFileW(lpFileName);
3988}
3989#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003990
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003991PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003992"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003993Remove a file (same as remove()).\n\
3994\n\
3995If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3996 and path should be relative; path will then be relative to that directory.\n\
3997dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003998 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003999
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004000PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004001"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004002Remove a file (same as unlink()).\n\
4003\n\
4004If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4005 and path should be relative; path will then be relative to that directory.\n\
4006dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004007 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004008
Barry Warsaw53699e91996-12-10 23:23:01 +00004009static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004010posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004011{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004012 path_t path;
4013 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004014 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004015 int result;
4016 PyObject *return_value = NULL;
4017
4018 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004019 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004020 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004021 path_converter, &path,
4022#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004023 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004024#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004025 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004026#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004027 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004028 return NULL;
4029
4030 Py_BEGIN_ALLOW_THREADS
4031#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004032 if (path.wide)
4033 result = Py_DeleteFileW(path.wide);
4034 else
4035 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004036 result = !result; /* Windows, success=1, UNIX, success=0 */
4037#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004038#ifdef HAVE_UNLINKAT
4039 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004040 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004041 else
4042#endif /* HAVE_UNLINKAT */
4043 result = unlink(path.narrow);
4044#endif
4045 Py_END_ALLOW_THREADS
4046
4047 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004048 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004049 goto exit;
4050 }
4051
4052 return_value = Py_None;
4053 Py_INCREF(Py_None);
4054
4055exit:
4056 path_cleanup(&path);
4057 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004058}
4059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004060
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004061PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004062"uname() -> uname_result\n\n\
4063Return an object identifying the current operating system.\n\
4064The object behaves like a named tuple with the following fields:\n\
4065 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004066
Larry Hastings605a62d2012-06-24 04:33:36 -07004067static PyStructSequence_Field uname_result_fields[] = {
4068 {"sysname", "operating system name"},
4069 {"nodename", "name of machine on network (implementation-defined)"},
4070 {"release", "operating system release"},
4071 {"version", "operating system version"},
4072 {"machine", "hardware identifier"},
4073 {NULL}
4074};
4075
4076PyDoc_STRVAR(uname_result__doc__,
4077"uname_result: Result from os.uname().\n\n\
4078This object may be accessed either as a tuple of\n\
4079 (sysname, nodename, release, version, machine),\n\
4080or via the attributes sysname, nodename, release, version, and machine.\n\
4081\n\
4082See os.uname for more information.");
4083
4084static PyStructSequence_Desc uname_result_desc = {
4085 "uname_result", /* name */
4086 uname_result__doc__, /* doc */
4087 uname_result_fields,
4088 5
4089};
4090
4091static PyTypeObject UnameResultType;
4092
4093
4094#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004095static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004096posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004097{
Victor Stinner8c62be82010-05-06 00:08:46 +00004098 struct utsname u;
4099 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004100 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004101
Victor Stinner8c62be82010-05-06 00:08:46 +00004102 Py_BEGIN_ALLOW_THREADS
4103 res = uname(&u);
4104 Py_END_ALLOW_THREADS
4105 if (res < 0)
4106 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004107
4108 value = PyStructSequence_New(&UnameResultType);
4109 if (value == NULL)
4110 return NULL;
4111
4112#define SET(i, field) \
4113 { \
4114 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4115 if (!o) { \
4116 Py_DECREF(value); \
4117 return NULL; \
4118 } \
4119 PyStructSequence_SET_ITEM(value, i, o); \
4120 } \
4121
4122 SET(0, u.sysname);
4123 SET(1, u.nodename);
4124 SET(2, u.release);
4125 SET(3, u.version);
4126 SET(4, u.machine);
4127
4128#undef SET
4129
4130 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004131}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004132#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004133
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004134
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135PyDoc_STRVAR(posix_utime__doc__,
4136"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4137Set the access and modified time of path.\n\
4138\n\
4139path may always be specified as a string.\n\
4140On some platforms, path may also be specified as an open file descriptor.\n\
4141 If this functionality is unavailable, using it raises an exception.\n\
4142\n\
4143If times is not None, it must be a tuple (atime, mtime);\n\
4144 atime and mtime should be expressed as float seconds since the epoch.\n\
4145If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4146 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4147 since the epoch.\n\
4148If both times and ns are None, utime uses the current time.\n\
4149Specifying tuples for both times and ns is an error.\n\
4150\n\
4151If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4152 and path should be relative; path will then be relative to that directory.\n\
4153If follow_symlinks is False, and the last element of the path is a symbolic\n\
4154 link, utime will modify the symbolic link itself instead of the file the\n\
4155 link points to.\n\
4156It is an error to use dir_fd or follow_symlinks when specifying path\n\
4157 as an open file descriptor.\n\
4158dir_fd and follow_symlinks may not be available on your platform.\n\
4159 If they are unavailable, using them will raise a NotImplementedError.");
4160
4161typedef struct {
4162 int now;
4163 time_t atime_s;
4164 long atime_ns;
4165 time_t mtime_s;
4166 long mtime_ns;
4167} utime_t;
4168
4169/*
4170 * these macros assume that "utime" is a pointer to a utime_t
4171 * they also intentionally leak the declaration of a pointer named "time"
4172 */
4173#define UTIME_TO_TIMESPEC \
4174 struct timespec ts[2]; \
4175 struct timespec *time; \
4176 if (utime->now) \
4177 time = NULL; \
4178 else { \
4179 ts[0].tv_sec = utime->atime_s; \
4180 ts[0].tv_nsec = utime->atime_ns; \
4181 ts[1].tv_sec = utime->mtime_s; \
4182 ts[1].tv_nsec = utime->mtime_ns; \
4183 time = ts; \
4184 } \
4185
4186#define UTIME_TO_TIMEVAL \
4187 struct timeval tv[2]; \
4188 struct timeval *time; \
4189 if (utime->now) \
4190 time = NULL; \
4191 else { \
4192 tv[0].tv_sec = utime->atime_s; \
4193 tv[0].tv_usec = utime->atime_ns / 1000; \
4194 tv[1].tv_sec = utime->mtime_s; \
4195 tv[1].tv_usec = utime->mtime_ns / 1000; \
4196 time = tv; \
4197 } \
4198
4199#define UTIME_TO_UTIMBUF \
4200 struct utimbuf u[2]; \
4201 struct utimbuf *time; \
4202 if (utime->now) \
4203 time = NULL; \
4204 else { \
4205 u.actime = utime->atime_s; \
4206 u.modtime = utime->mtime_s; \
4207 time = u; \
4208 }
4209
4210#define UTIME_TO_TIME_T \
4211 time_t timet[2]; \
4212 struct timet time; \
4213 if (utime->now) \
4214 time = NULL; \
4215 else { \
4216 timet[0] = utime->atime_s; \
4217 timet[1] = utime->mtime_s; \
4218 time = &timet; \
4219 } \
4220
4221
4222#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4223
4224#if UTIME_HAVE_DIR_FD
4225
4226static int
4227utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4228{
4229#ifdef HAVE_UTIMENSAT
4230 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4231 UTIME_TO_TIMESPEC;
4232 return utimensat(dir_fd, path, time, flags);
4233#elif defined(HAVE_FUTIMESAT)
4234 UTIME_TO_TIMEVAL;
4235 /*
4236 * follow_symlinks will never be false here;
4237 * we only allow !follow_symlinks and dir_fd together
4238 * if we have utimensat()
4239 */
4240 assert(follow_symlinks);
4241 return futimesat(dir_fd, path, time);
4242#endif
4243}
4244
4245#endif
4246
4247#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4248
4249#if UTIME_HAVE_FD
4250
4251static int
4252utime_fd(utime_t *utime, int fd)
4253{
4254#ifdef HAVE_FUTIMENS
4255 UTIME_TO_TIMESPEC;
4256 return futimens(fd, time);
4257#else
4258 UTIME_TO_TIMEVAL;
4259 return futimes(fd, time);
4260#endif
4261}
4262
4263#endif
4264
4265
4266#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4267 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4268
4269#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4270
4271static int
4272utime_nofollow_symlinks(utime_t *utime, char *path)
4273{
4274#ifdef HAVE_UTIMENSAT
4275 UTIME_TO_TIMESPEC;
4276 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4277#else
4278 UTIME_TO_TIMEVAL;
4279 return lutimes(path, time);
4280#endif
4281}
4282
4283#endif
4284
4285#ifndef MS_WINDOWS
4286
4287static int
4288utime_default(utime_t *utime, char *path)
4289{
4290#ifdef HAVE_UTIMENSAT
4291 UTIME_TO_TIMESPEC;
4292 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4293#elif defined(HAVE_UTIMES)
4294 UTIME_TO_TIMEVAL;
4295 return utimes(path, time);
4296#elif defined(HAVE_UTIME_H)
4297 UTIME_TO_UTIMBUF;
4298 return utime(path, time);
4299#else
4300 UTIME_TO_TIME_T;
4301 return utime(path, time);
4302#endif
4303}
4304
4305#endif
4306
Larry Hastings76ad59b2012-05-03 00:30:07 -07004307static int
4308split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4309{
4310 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004311 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004312 divmod = PyNumber_Divmod(py_long, billion);
4313 if (!divmod)
4314 goto exit;
4315 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4316 if ((*s == -1) && PyErr_Occurred())
4317 goto exit;
4318 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004319 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004320 goto exit;
4321
4322 result = 1;
4323exit:
4324 Py_XDECREF(divmod);
4325 return result;
4326}
4327
Larry Hastings9cf065c2012-06-22 16:30:09 -07004328static PyObject *
4329posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004330{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004331 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004332 PyObject *times = NULL;
4333 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004334 int dir_fd = DEFAULT_DIR_FD;
4335 int follow_symlinks = 1;
4336 char *keywords[] = {"path", "times", "ns", "dir_fd",
4337 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004338
Larry Hastings9cf065c2012-06-22 16:30:09 -07004339 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004340
Larry Hastings9cf065c2012-06-22 16:30:09 -07004341#ifdef MS_WINDOWS
4342 HANDLE hFile;
4343 FILETIME atime, mtime;
4344#else
4345 int result;
4346#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004347
Larry Hastings9cf065c2012-06-22 16:30:09 -07004348 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004349
Larry Hastings9cf065c2012-06-22 16:30:09 -07004350 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004351 path.function_name = "utime";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004352#if UTIME_HAVE_FD
4353 path.allow_fd = 1;
4354#endif
4355 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4356 "O&|O$OO&p:utime", keywords,
4357 path_converter, &path,
4358 &times, &ns,
4359#if UTIME_HAVE_DIR_FD
4360 dir_fd_converter, &dir_fd,
4361#else
4362 dir_fd_unavailable, &dir_fd,
4363#endif
4364 &follow_symlinks
4365 ))
4366 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004367
Larry Hastings9cf065c2012-06-22 16:30:09 -07004368 if (times && (times != Py_None) && ns) {
4369 PyErr_SetString(PyExc_ValueError,
4370 "utime: you may specify either 'times'"
4371 " or 'ns' but not both");
4372 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004373 }
4374
4375 if (times && (times != Py_None)) {
4376 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004377 PyErr_SetString(PyExc_TypeError,
4378 "utime: 'times' must be either"
4379 " a tuple of two ints or None");
4380 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004381 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004383 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004385 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386 &utime.mtime_s, &utime.mtime_ns) == -1) {
4387 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004388 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004389 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004390 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004391 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004392 PyErr_SetString(PyExc_TypeError,
4393 "utime: 'ns' must be a tuple of two ints");
4394 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004395 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004396 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004397 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004398 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004399 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004400 &utime.mtime_s, &utime.mtime_ns)) {
4401 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004402 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403 }
4404 else {
4405 /* times and ns are both None/unspecified. use "now". */
4406 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004407 }
4408
Larry Hastings9cf065c2012-06-22 16:30:09 -07004409#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4410 if (follow_symlinks_specified("utime", follow_symlinks))
4411 goto exit;
4412#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004413
Larry Hastings9cf065c2012-06-22 16:30:09 -07004414 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4415 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4416 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4417 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004418
Larry Hastings9cf065c2012-06-22 16:30:09 -07004419#if !defined(HAVE_UTIMENSAT)
4420 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004421 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004422 "utime: cannot use dir_fd and follow_symlinks "
4423 "together on this platform");
4424 goto exit;
4425 }
4426#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004427
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004428#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004429 Py_BEGIN_ALLOW_THREADS
4430 if (path.wide)
4431 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004432 NULL, OPEN_EXISTING,
4433 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004434 else
4435 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 NULL, OPEN_EXISTING,
4437 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004438 Py_END_ALLOW_THREADS
4439 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004440 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004441 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004442 }
4443
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004445 SYSTEMTIME now;
4446 GetSystemTime(&now);
4447 if (!SystemTimeToFileTime(&now, &mtime) ||
4448 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004449 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004451 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004452 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004453 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004454 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4455 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004456 }
4457 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4458 /* Avoid putting the file name into the error here,
4459 as that may confuse the user into believing that
4460 something is wrong with the file, when it also
4461 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004462 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004463 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004464 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004465#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004466 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004467
Larry Hastings9cf065c2012-06-22 16:30:09 -07004468#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4469 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4470 result = utime_nofollow_symlinks(&utime, path.narrow);
4471 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004472#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004473
4474#if UTIME_HAVE_DIR_FD
4475 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4476 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4477 else
4478#endif
4479
4480#if UTIME_HAVE_FD
4481 if (path.fd != -1)
4482 result = utime_fd(&utime, path.fd);
4483 else
4484#endif
4485
4486 result = utime_default(&utime, path.narrow);
4487
4488 Py_END_ALLOW_THREADS
4489
4490 if (result < 0) {
4491 /* see previous comment about not putting filename in error here */
4492 return_value = posix_error();
4493 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004494 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004495
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004496#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004497
4498 Py_INCREF(Py_None);
4499 return_value = Py_None;
4500
4501exit:
4502 path_cleanup(&path);
4503#ifdef MS_WINDOWS
4504 if (hFile != INVALID_HANDLE_VALUE)
4505 CloseHandle(hFile);
4506#endif
4507 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004508}
4509
Guido van Rossum3b066191991-06-04 19:40:25 +00004510/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004511
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004512PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004513"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004514Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004515
Barry Warsaw53699e91996-12-10 23:23:01 +00004516static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004517posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004518{
Victor Stinner8c62be82010-05-06 00:08:46 +00004519 int sts;
4520 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4521 return NULL;
4522 _exit(sts);
4523 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004524}
4525
Martin v. Löwis114619e2002-10-07 06:44:21 +00004526#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4527static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004528free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004529{
Victor Stinner8c62be82010-05-06 00:08:46 +00004530 Py_ssize_t i;
4531 for (i = 0; i < count; i++)
4532 PyMem_Free(array[i]);
4533 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004534}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004535
Antoine Pitrou69f71142009-05-24 21:25:49 +00004536static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004537int fsconvert_strdup(PyObject *o, char**out)
4538{
Victor Stinner8c62be82010-05-06 00:08:46 +00004539 PyObject *bytes;
4540 Py_ssize_t size;
4541 if (!PyUnicode_FSConverter(o, &bytes))
4542 return 0;
4543 size = PyBytes_GET_SIZE(bytes);
4544 *out = PyMem_Malloc(size+1);
4545 if (!*out)
4546 return 0;
4547 memcpy(*out, PyBytes_AsString(bytes), size+1);
4548 Py_DECREF(bytes);
4549 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004550}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004551#endif
4552
Ross Lagerwall7807c352011-03-17 20:20:30 +02004553#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004554static char**
4555parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4556{
Victor Stinner8c62be82010-05-06 00:08:46 +00004557 char **envlist;
4558 Py_ssize_t i, pos, envc;
4559 PyObject *keys=NULL, *vals=NULL;
4560 PyObject *key, *val, *key2, *val2;
4561 char *p, *k, *v;
4562 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004563
Victor Stinner8c62be82010-05-06 00:08:46 +00004564 i = PyMapping_Size(env);
4565 if (i < 0)
4566 return NULL;
4567 envlist = PyMem_NEW(char *, i + 1);
4568 if (envlist == NULL) {
4569 PyErr_NoMemory();
4570 return NULL;
4571 }
4572 envc = 0;
4573 keys = PyMapping_Keys(env);
4574 vals = PyMapping_Values(env);
4575 if (!keys || !vals)
4576 goto error;
4577 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4578 PyErr_Format(PyExc_TypeError,
4579 "env.keys() or env.values() is not a list");
4580 goto error;
4581 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004582
Victor Stinner8c62be82010-05-06 00:08:46 +00004583 for (pos = 0; pos < i; pos++) {
4584 key = PyList_GetItem(keys, pos);
4585 val = PyList_GetItem(vals, pos);
4586 if (!key || !val)
4587 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004588
Victor Stinner8c62be82010-05-06 00:08:46 +00004589 if (PyUnicode_FSConverter(key, &key2) == 0)
4590 goto error;
4591 if (PyUnicode_FSConverter(val, &val2) == 0) {
4592 Py_DECREF(key2);
4593 goto error;
4594 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004595
Victor Stinner8c62be82010-05-06 00:08:46 +00004596 k = PyBytes_AsString(key2);
4597 v = PyBytes_AsString(val2);
4598 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004599
Victor Stinner8c62be82010-05-06 00:08:46 +00004600 p = PyMem_NEW(char, len);
4601 if (p == NULL) {
4602 PyErr_NoMemory();
4603 Py_DECREF(key2);
4604 Py_DECREF(val2);
4605 goto error;
4606 }
4607 PyOS_snprintf(p, len, "%s=%s", k, v);
4608 envlist[envc++] = p;
4609 Py_DECREF(key2);
4610 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004611 }
4612 Py_DECREF(vals);
4613 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004614
Victor Stinner8c62be82010-05-06 00:08:46 +00004615 envlist[envc] = 0;
4616 *envc_ptr = envc;
4617 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004618
4619error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004620 Py_XDECREF(keys);
4621 Py_XDECREF(vals);
4622 while (--envc >= 0)
4623 PyMem_DEL(envlist[envc]);
4624 PyMem_DEL(envlist);
4625 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004626}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004627
Ross Lagerwall7807c352011-03-17 20:20:30 +02004628static char**
4629parse_arglist(PyObject* argv, Py_ssize_t *argc)
4630{
4631 int i;
4632 char **argvlist = PyMem_NEW(char *, *argc+1);
4633 if (argvlist == NULL) {
4634 PyErr_NoMemory();
4635 return NULL;
4636 }
4637 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004638 PyObject* item = PySequence_ITEM(argv, i);
4639 if (item == NULL)
4640 goto fail;
4641 if (!fsconvert_strdup(item, &argvlist[i])) {
4642 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004643 goto fail;
4644 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004645 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004646 }
4647 argvlist[*argc] = NULL;
4648 return argvlist;
4649fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004650 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004651 free_string_array(argvlist, *argc);
4652 return NULL;
4653}
4654#endif
4655
4656#ifdef HAVE_EXECV
4657PyDoc_STRVAR(posix_execv__doc__,
4658"execv(path, args)\n\n\
4659Execute an executable path with arguments, replacing current process.\n\
4660\n\
4661 path: path of executable file\n\
4662 args: tuple or list of strings");
4663
4664static PyObject *
4665posix_execv(PyObject *self, PyObject *args)
4666{
4667 PyObject *opath;
4668 char *path;
4669 PyObject *argv;
4670 char **argvlist;
4671 Py_ssize_t argc;
4672
4673 /* execv has two arguments: (path, argv), where
4674 argv is a list or tuple of strings. */
4675
4676 if (!PyArg_ParseTuple(args, "O&O:execv",
4677 PyUnicode_FSConverter,
4678 &opath, &argv))
4679 return NULL;
4680 path = PyBytes_AsString(opath);
4681 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4682 PyErr_SetString(PyExc_TypeError,
4683 "execv() arg 2 must be a tuple or list");
4684 Py_DECREF(opath);
4685 return NULL;
4686 }
4687 argc = PySequence_Size(argv);
4688 if (argc < 1) {
4689 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4690 Py_DECREF(opath);
4691 return NULL;
4692 }
4693
4694 argvlist = parse_arglist(argv, &argc);
4695 if (argvlist == NULL) {
4696 Py_DECREF(opath);
4697 return NULL;
4698 }
4699
4700 execv(path, argvlist);
4701
4702 /* If we get here it's definitely an error */
4703
4704 free_string_array(argvlist, argc);
4705 Py_DECREF(opath);
4706 return posix_error();
4707}
4708
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004709PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004710"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004711Execute a path with arguments and environment, replacing current process.\n\
4712\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004713 path: path of executable file\n\
4714 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 env: dictionary of strings mapping to strings\n\
4716\n\
4717On some platforms, you may specify an open file descriptor for path;\n\
4718 execve will execute the program the file descriptor is open to.\n\
4719 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004720
Barry Warsaw53699e91996-12-10 23:23:01 +00004721static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004723{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004724 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004725 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004726 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004727 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004728 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004730
Victor Stinner8c62be82010-05-06 00:08:46 +00004731 /* execve has three arguments: (path, argv, env), where
4732 argv is a list or tuple of strings and env is a dictionary
4733 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004734
Larry Hastings9cf065c2012-06-22 16:30:09 -07004735 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004736 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737#ifdef HAVE_FEXECVE
4738 path.allow_fd = 1;
4739#endif
4740 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4741 path_converter, &path,
4742 &argv, &env
4743 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004744 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745
Ross Lagerwall7807c352011-03-17 20:20:30 +02004746 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004747 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748 "execve: argv must be a tuple or list");
4749 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004750 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004751 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004752 if (!PyMapping_Check(env)) {
4753 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004754 "execve: environment must be a mapping object");
4755 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004756 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004757
Ross Lagerwall7807c352011-03-17 20:20:30 +02004758 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004759 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004760 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004761 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004762
Victor Stinner8c62be82010-05-06 00:08:46 +00004763 envlist = parse_envlist(env, &envc);
4764 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004765 goto fail;
4766
Larry Hastings9cf065c2012-06-22 16:30:09 -07004767#ifdef HAVE_FEXECVE
4768 if (path.fd > -1)
4769 fexecve(path.fd, argvlist, envlist);
4770 else
4771#endif
4772 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004773
4774 /* If we get here it's definitely an error */
4775
Victor Stinner292c8352012-10-30 02:17:38 +01004776 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004777
4778 while (--envc >= 0)
4779 PyMem_DEL(envlist[envc]);
4780 PyMem_DEL(envlist);
4781 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782 if (argvlist)
4783 free_string_array(argvlist, argc);
4784 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004785 return NULL;
4786}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004787#endif /* HAVE_EXECV */
4788
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004789
Guido van Rossuma1065681999-01-25 23:20:23 +00004790#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004791PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004792"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004793Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004794\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004795 mode: mode of process creation\n\
4796 path: path of executable file\n\
4797 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004798
4799static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004800posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004801{
Victor Stinner8c62be82010-05-06 00:08:46 +00004802 PyObject *opath;
4803 char *path;
4804 PyObject *argv;
4805 char **argvlist;
4806 int mode, i;
4807 Py_ssize_t argc;
4808 Py_intptr_t spawnval;
4809 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004810
Victor Stinner8c62be82010-05-06 00:08:46 +00004811 /* spawnv has three arguments: (mode, path, argv), where
4812 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004813
Victor Stinner8c62be82010-05-06 00:08:46 +00004814 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4815 PyUnicode_FSConverter,
4816 &opath, &argv))
4817 return NULL;
4818 path = PyBytes_AsString(opath);
4819 if (PyList_Check(argv)) {
4820 argc = PyList_Size(argv);
4821 getitem = PyList_GetItem;
4822 }
4823 else if (PyTuple_Check(argv)) {
4824 argc = PyTuple_Size(argv);
4825 getitem = PyTuple_GetItem;
4826 }
4827 else {
4828 PyErr_SetString(PyExc_TypeError,
4829 "spawnv() arg 2 must be a tuple or list");
4830 Py_DECREF(opath);
4831 return NULL;
4832 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004833
Victor Stinner8c62be82010-05-06 00:08:46 +00004834 argvlist = PyMem_NEW(char *, argc+1);
4835 if (argvlist == NULL) {
4836 Py_DECREF(opath);
4837 return PyErr_NoMemory();
4838 }
4839 for (i = 0; i < argc; i++) {
4840 if (!fsconvert_strdup((*getitem)(argv, i),
4841 &argvlist[i])) {
4842 free_string_array(argvlist, i);
4843 PyErr_SetString(
4844 PyExc_TypeError,
4845 "spawnv() arg 2 must contain only strings");
4846 Py_DECREF(opath);
4847 return NULL;
4848 }
4849 }
4850 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004851
Victor Stinner8c62be82010-05-06 00:08:46 +00004852 if (mode == _OLD_P_OVERLAY)
4853 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004854
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 Py_BEGIN_ALLOW_THREADS
4856 spawnval = _spawnv(mode, path, argvlist);
4857 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00004858
Victor Stinner8c62be82010-05-06 00:08:46 +00004859 free_string_array(argvlist, argc);
4860 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004861
Victor Stinner8c62be82010-05-06 00:08:46 +00004862 if (spawnval == -1)
4863 return posix_error();
4864 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004865#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004866 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004867#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004868 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004869#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004870}
4871
4872
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004873PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004874"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004875Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004876\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004877 mode: mode of process creation\n\
4878 path: path of executable file\n\
4879 args: tuple or list of arguments\n\
4880 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004881
4882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004883posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004884{
Victor Stinner8c62be82010-05-06 00:08:46 +00004885 PyObject *opath;
4886 char *path;
4887 PyObject *argv, *env;
4888 char **argvlist;
4889 char **envlist;
4890 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004891 int mode;
4892 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004893 Py_intptr_t spawnval;
4894 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4895 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004896
Victor Stinner8c62be82010-05-06 00:08:46 +00004897 /* spawnve has four arguments: (mode, path, argv, env), where
4898 argv is a list or tuple of strings and env is a dictionary
4899 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004900
Victor Stinner8c62be82010-05-06 00:08:46 +00004901 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4902 PyUnicode_FSConverter,
4903 &opath, &argv, &env))
4904 return NULL;
4905 path = PyBytes_AsString(opath);
4906 if (PyList_Check(argv)) {
4907 argc = PyList_Size(argv);
4908 getitem = PyList_GetItem;
4909 }
4910 else if (PyTuple_Check(argv)) {
4911 argc = PyTuple_Size(argv);
4912 getitem = PyTuple_GetItem;
4913 }
4914 else {
4915 PyErr_SetString(PyExc_TypeError,
4916 "spawnve() arg 2 must be a tuple or list");
4917 goto fail_0;
4918 }
4919 if (!PyMapping_Check(env)) {
4920 PyErr_SetString(PyExc_TypeError,
4921 "spawnve() arg 3 must be a mapping object");
4922 goto fail_0;
4923 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004924
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 argvlist = PyMem_NEW(char *, argc+1);
4926 if (argvlist == NULL) {
4927 PyErr_NoMemory();
4928 goto fail_0;
4929 }
4930 for (i = 0; i < argc; i++) {
4931 if (!fsconvert_strdup((*getitem)(argv, i),
4932 &argvlist[i]))
4933 {
4934 lastarg = i;
4935 goto fail_1;
4936 }
4937 }
4938 lastarg = argc;
4939 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004940
Victor Stinner8c62be82010-05-06 00:08:46 +00004941 envlist = parse_envlist(env, &envc);
4942 if (envlist == NULL)
4943 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004944
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 if (mode == _OLD_P_OVERLAY)
4946 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004947
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 Py_BEGIN_ALLOW_THREADS
4949 spawnval = _spawnve(mode, path, argvlist, envlist);
4950 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00004951
Victor Stinner8c62be82010-05-06 00:08:46 +00004952 if (spawnval == -1)
4953 (void) posix_error();
4954 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004955#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004956 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004957#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004958 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004959#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004960
Victor Stinner8c62be82010-05-06 00:08:46 +00004961 while (--envc >= 0)
4962 PyMem_DEL(envlist[envc]);
4963 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004964 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004965 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004966 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 Py_DECREF(opath);
4968 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004969}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004970
Guido van Rossuma1065681999-01-25 23:20:23 +00004971#endif /* HAVE_SPAWNV */
4972
4973
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004974#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004975PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004976"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004977Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4978\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004979Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004980
4981static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004982posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004983{
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 pid_t pid;
4985 int result = 0;
4986 _PyImport_AcquireLock();
4987 pid = fork1();
4988 if (pid == 0) {
4989 /* child: this clobbers and resets the import lock. */
4990 PyOS_AfterFork();
4991 } else {
4992 /* parent: release the import lock. */
4993 result = _PyImport_ReleaseLock();
4994 }
4995 if (pid == -1)
4996 return posix_error();
4997 if (result < 0) {
4998 /* Don't clobber the OSError if the fork failed. */
4999 PyErr_SetString(PyExc_RuntimeError,
5000 "not holding the import lock");
5001 return NULL;
5002 }
5003 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005004}
5005#endif
5006
5007
Guido van Rossumad0ee831995-03-01 10:34:45 +00005008#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005009PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005010"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005011Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005012Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005013
Barry Warsaw53699e91996-12-10 23:23:01 +00005014static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005015posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005016{
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 pid_t pid;
5018 int result = 0;
5019 _PyImport_AcquireLock();
5020 pid = fork();
5021 if (pid == 0) {
5022 /* child: this clobbers and resets the import lock. */
5023 PyOS_AfterFork();
5024 } else {
5025 /* parent: release the import lock. */
5026 result = _PyImport_ReleaseLock();
5027 }
5028 if (pid == -1)
5029 return posix_error();
5030 if (result < 0) {
5031 /* Don't clobber the OSError if the fork failed. */
5032 PyErr_SetString(PyExc_RuntimeError,
5033 "not holding the import lock");
5034 return NULL;
5035 }
5036 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005037}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005038#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005039
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005040#ifdef HAVE_SCHED_H
5041
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005042#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5043
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005044PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5045"sched_get_priority_max(policy)\n\n\
5046Get the maximum scheduling priority for *policy*.");
5047
5048static PyObject *
5049posix_sched_get_priority_max(PyObject *self, PyObject *args)
5050{
5051 int policy, max;
5052
5053 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5054 return NULL;
5055 max = sched_get_priority_max(policy);
5056 if (max < 0)
5057 return posix_error();
5058 return PyLong_FromLong(max);
5059}
5060
5061PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5062"sched_get_priority_min(policy)\n\n\
5063Get the minimum scheduling priority for *policy*.");
5064
5065static PyObject *
5066posix_sched_get_priority_min(PyObject *self, PyObject *args)
5067{
5068 int policy, min;
5069
5070 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5071 return NULL;
5072 min = sched_get_priority_min(policy);
5073 if (min < 0)
5074 return posix_error();
5075 return PyLong_FromLong(min);
5076}
5077
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005078#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5079
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005080#ifdef HAVE_SCHED_SETSCHEDULER
5081
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005082PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5083"sched_getscheduler(pid)\n\n\
5084Get the scheduling policy for the process with a PID of *pid*.\n\
5085Passing a PID of 0 returns the scheduling policy for the calling process.");
5086
5087static PyObject *
5088posix_sched_getscheduler(PyObject *self, PyObject *args)
5089{
5090 pid_t pid;
5091 int policy;
5092
5093 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5094 return NULL;
5095 policy = sched_getscheduler(pid);
5096 if (policy < 0)
5097 return posix_error();
5098 return PyLong_FromLong(policy);
5099}
5100
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005101#endif
5102
5103#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5104
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005105static PyObject *
5106sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5107{
5108 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005109 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005110
5111 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5112 return NULL;
5113 res = PyStructSequence_New(type);
5114 if (!res)
5115 return NULL;
5116 Py_INCREF(priority);
5117 PyStructSequence_SET_ITEM(res, 0, priority);
5118 return res;
5119}
5120
5121PyDoc_STRVAR(sched_param__doc__,
5122"sched_param(sched_priority): A scheduling parameter.\n\n\
5123Current has only one field: sched_priority");
5124
5125static PyStructSequence_Field sched_param_fields[] = {
5126 {"sched_priority", "the scheduling priority"},
5127 {0}
5128};
5129
5130static PyStructSequence_Desc sched_param_desc = {
5131 "sched_param", /* name */
5132 sched_param__doc__, /* doc */
5133 sched_param_fields,
5134 1
5135};
5136
5137static int
5138convert_sched_param(PyObject *param, struct sched_param *res)
5139{
5140 long priority;
5141
5142 if (Py_TYPE(param) != &SchedParamType) {
5143 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5144 return 0;
5145 }
5146 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5147 if (priority == -1 && PyErr_Occurred())
5148 return 0;
5149 if (priority > INT_MAX || priority < INT_MIN) {
5150 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5151 return 0;
5152 }
5153 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5154 return 1;
5155}
5156
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005157#endif
5158
5159#ifdef HAVE_SCHED_SETSCHEDULER
5160
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005161PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5162"sched_setscheduler(pid, policy, param)\n\n\
5163Set the scheduling policy, *policy*, for *pid*.\n\
5164If *pid* is 0, the calling process is changed.\n\
5165*param* is an instance of sched_param.");
5166
5167static PyObject *
5168posix_sched_setscheduler(PyObject *self, PyObject *args)
5169{
5170 pid_t pid;
5171 int policy;
5172 struct sched_param param;
5173
5174 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5175 &pid, &policy, &convert_sched_param, &param))
5176 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005177
5178 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005179 ** sched_setscheduler() returns 0 in Linux, but the previous
5180 ** scheduling policy under Solaris/Illumos, and others.
5181 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005182 */
5183 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005184 return posix_error();
5185 Py_RETURN_NONE;
5186}
5187
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005188#endif
5189
5190#ifdef HAVE_SCHED_SETPARAM
5191
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005192PyDoc_STRVAR(posix_sched_getparam__doc__,
5193"sched_getparam(pid) -> sched_param\n\n\
5194Returns scheduling parameters for the process with *pid* as an instance of the\n\
5195sched_param class. A PID of 0 means the calling process.");
5196
5197static PyObject *
5198posix_sched_getparam(PyObject *self, PyObject *args)
5199{
5200 pid_t pid;
5201 struct sched_param param;
5202 PyObject *res, *priority;
5203
5204 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5205 return NULL;
5206 if (sched_getparam(pid, &param))
5207 return posix_error();
5208 res = PyStructSequence_New(&SchedParamType);
5209 if (!res)
5210 return NULL;
5211 priority = PyLong_FromLong(param.sched_priority);
5212 if (!priority) {
5213 Py_DECREF(res);
5214 return NULL;
5215 }
5216 PyStructSequence_SET_ITEM(res, 0, priority);
5217 return res;
5218}
5219
5220PyDoc_STRVAR(posix_sched_setparam__doc__,
5221"sched_setparam(pid, param)\n\n\
5222Set scheduling parameters for a process with PID *pid*.\n\
5223A PID of 0 means the calling process.");
5224
5225static PyObject *
5226posix_sched_setparam(PyObject *self, PyObject *args)
5227{
5228 pid_t pid;
5229 struct sched_param param;
5230
5231 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5232 &pid, &convert_sched_param, &param))
5233 return NULL;
5234 if (sched_setparam(pid, &param))
5235 return posix_error();
5236 Py_RETURN_NONE;
5237}
5238
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005239#endif
5240
5241#ifdef HAVE_SCHED_RR_GET_INTERVAL
5242
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005243PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5244"sched_rr_get_interval(pid) -> float\n\n\
5245Return the round-robin quantum for the process with PID *pid* in seconds.");
5246
5247static PyObject *
5248posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5249{
5250 pid_t pid;
5251 struct timespec interval;
5252
5253 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5254 return NULL;
5255 if (sched_rr_get_interval(pid, &interval))
5256 return posix_error();
5257 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5258}
5259
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005260#endif
5261
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005262PyDoc_STRVAR(posix_sched_yield__doc__,
5263"sched_yield()\n\n\
5264Voluntarily relinquish the CPU.");
5265
5266static PyObject *
5267posix_sched_yield(PyObject *self, PyObject *noargs)
5268{
5269 if (sched_yield())
5270 return posix_error();
5271 Py_RETURN_NONE;
5272}
5273
Benjamin Peterson2740af82011-08-02 17:41:34 -05005274#ifdef HAVE_SCHED_SETAFFINITY
5275
Antoine Pitrou84869872012-08-04 16:16:35 +02005276/* The minimum number of CPUs allocated in a cpu_set_t */
5277static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005278
5279PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5280"sched_setaffinity(pid, cpu_set)\n\n\
5281Set the affinity of the process with PID *pid* to *cpu_set*.");
5282
5283static PyObject *
5284posix_sched_setaffinity(PyObject *self, PyObject *args)
5285{
5286 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005287 int ncpus;
5288 size_t setsize;
5289 cpu_set_t *mask = NULL;
5290 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005291
Antoine Pitrou84869872012-08-04 16:16:35 +02005292 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5293 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005294 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005295
5296 iterator = PyObject_GetIter(iterable);
5297 if (iterator == NULL)
5298 return NULL;
5299
5300 ncpus = NCPUS_START;
5301 setsize = CPU_ALLOC_SIZE(ncpus);
5302 mask = CPU_ALLOC(ncpus);
5303 if (mask == NULL) {
5304 PyErr_NoMemory();
5305 goto error;
5306 }
5307 CPU_ZERO_S(setsize, mask);
5308
5309 while ((item = PyIter_Next(iterator))) {
5310 long cpu;
5311 if (!PyLong_Check(item)) {
5312 PyErr_Format(PyExc_TypeError,
5313 "expected an iterator of ints, "
5314 "but iterator yielded %R",
5315 Py_TYPE(item));
5316 Py_DECREF(item);
5317 goto error;
5318 }
5319 cpu = PyLong_AsLong(item);
5320 Py_DECREF(item);
5321 if (cpu < 0) {
5322 if (!PyErr_Occurred())
5323 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5324 goto error;
5325 }
5326 if (cpu > INT_MAX - 1) {
5327 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5328 goto error;
5329 }
5330 if (cpu >= ncpus) {
5331 /* Grow CPU mask to fit the CPU number */
5332 int newncpus = ncpus;
5333 cpu_set_t *newmask;
5334 size_t newsetsize;
5335 while (newncpus <= cpu) {
5336 if (newncpus > INT_MAX / 2)
5337 newncpus = cpu + 1;
5338 else
5339 newncpus = newncpus * 2;
5340 }
5341 newmask = CPU_ALLOC(newncpus);
5342 if (newmask == NULL) {
5343 PyErr_NoMemory();
5344 goto error;
5345 }
5346 newsetsize = CPU_ALLOC_SIZE(newncpus);
5347 CPU_ZERO_S(newsetsize, newmask);
5348 memcpy(newmask, mask, setsize);
5349 CPU_FREE(mask);
5350 setsize = newsetsize;
5351 mask = newmask;
5352 ncpus = newncpus;
5353 }
5354 CPU_SET_S(cpu, setsize, mask);
5355 }
5356 Py_CLEAR(iterator);
5357
5358 if (sched_setaffinity(pid, setsize, mask)) {
5359 posix_error();
5360 goto error;
5361 }
5362 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005363 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005364
5365error:
5366 if (mask)
5367 CPU_FREE(mask);
5368 Py_XDECREF(iterator);
5369 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005370}
5371
5372PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5373"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5374Return the affinity of the process with PID *pid*.\n\
5375The returned cpu_set will be of size *ncpus*.");
5376
5377static PyObject *
5378posix_sched_getaffinity(PyObject *self, PyObject *args)
5379{
5380 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005381 int cpu, ncpus, count;
5382 size_t setsize;
5383 cpu_set_t *mask = NULL;
5384 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005385
Antoine Pitrou84869872012-08-04 16:16:35 +02005386 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5387 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005388 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005389
5390 ncpus = NCPUS_START;
5391 while (1) {
5392 setsize = CPU_ALLOC_SIZE(ncpus);
5393 mask = CPU_ALLOC(ncpus);
5394 if (mask == NULL)
5395 return PyErr_NoMemory();
5396 if (sched_getaffinity(pid, setsize, mask) == 0)
5397 break;
5398 CPU_FREE(mask);
5399 if (errno != EINVAL)
5400 return posix_error();
5401 if (ncpus > INT_MAX / 2) {
5402 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5403 "a large enough CPU set");
5404 return NULL;
5405 }
5406 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005407 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005408
5409 res = PySet_New(NULL);
5410 if (res == NULL)
5411 goto error;
5412 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5413 if (CPU_ISSET_S(cpu, setsize, mask)) {
5414 PyObject *cpu_num = PyLong_FromLong(cpu);
5415 --count;
5416 if (cpu_num == NULL)
5417 goto error;
5418 if (PySet_Add(res, cpu_num)) {
5419 Py_DECREF(cpu_num);
5420 goto error;
5421 }
5422 Py_DECREF(cpu_num);
5423 }
5424 }
5425 CPU_FREE(mask);
5426 return res;
5427
5428error:
5429 if (mask)
5430 CPU_FREE(mask);
5431 Py_XDECREF(res);
5432 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005433}
5434
Benjamin Peterson2740af82011-08-02 17:41:34 -05005435#endif /* HAVE_SCHED_SETAFFINITY */
5436
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005437#endif /* HAVE_SCHED_H */
5438
Neal Norwitzb59798b2003-03-21 01:43:31 +00005439/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005440/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5441#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005442#define DEV_PTY_FILE "/dev/ptc"
5443#define HAVE_DEV_PTMX
5444#else
5445#define DEV_PTY_FILE "/dev/ptmx"
5446#endif
5447
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005448#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005449#ifdef HAVE_PTY_H
5450#include <pty.h>
5451#else
5452#ifdef HAVE_LIBUTIL_H
5453#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005454#else
5455#ifdef HAVE_UTIL_H
5456#include <util.h>
5457#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005458#endif /* HAVE_LIBUTIL_H */
5459#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005460#ifdef HAVE_STROPTS_H
5461#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005462#endif
5463#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005464
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005465#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005466PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005467"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005468Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005469
5470static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005471posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005472{
Victor Stinner8c62be82010-05-06 00:08:46 +00005473 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005474#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005475 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005476#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005477#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005478 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005479#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005480 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005481#endif
5482#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005483
Thomas Wouters70c21a12000-07-14 14:28:33 +00005484#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005485 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5486 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005487#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005488 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5489 if (slave_name == NULL)
5490 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005491
Victor Stinner8c62be82010-05-06 00:08:46 +00005492 slave_fd = open(slave_name, O_RDWR);
5493 if (slave_fd < 0)
5494 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005495#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005496 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5497 if (master_fd < 0)
5498 return posix_error();
5499 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5500 /* change permission of slave */
5501 if (grantpt(master_fd) < 0) {
5502 PyOS_setsig(SIGCHLD, sig_saved);
5503 return posix_error();
5504 }
5505 /* unlock slave */
5506 if (unlockpt(master_fd) < 0) {
5507 PyOS_setsig(SIGCHLD, sig_saved);
5508 return posix_error();
5509 }
5510 PyOS_setsig(SIGCHLD, sig_saved);
5511 slave_name = ptsname(master_fd); /* get name of slave */
5512 if (slave_name == NULL)
5513 return posix_error();
5514 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5515 if (slave_fd < 0)
5516 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005517#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005518 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5519 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005520#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005521 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005522#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005523#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005524#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005525
Victor Stinner8c62be82010-05-06 00:08:46 +00005526 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005527
Fred Drake8cef4cf2000-06-28 16:40:38 +00005528}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005529#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005530
5531#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005532PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005533"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005534Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5535Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005536To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005537
5538static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005539posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005540{
Victor Stinner8c62be82010-05-06 00:08:46 +00005541 int master_fd = -1, result = 0;
5542 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005543
Victor Stinner8c62be82010-05-06 00:08:46 +00005544 _PyImport_AcquireLock();
5545 pid = forkpty(&master_fd, NULL, NULL, NULL);
5546 if (pid == 0) {
5547 /* child: this clobbers and resets the import lock. */
5548 PyOS_AfterFork();
5549 } else {
5550 /* parent: release the import lock. */
5551 result = _PyImport_ReleaseLock();
5552 }
5553 if (pid == -1)
5554 return posix_error();
5555 if (result < 0) {
5556 /* Don't clobber the OSError if the fork failed. */
5557 PyErr_SetString(PyExc_RuntimeError,
5558 "not holding the import lock");
5559 return NULL;
5560 }
5561 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005562}
5563#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005564
Ross Lagerwall7807c352011-03-17 20:20:30 +02005565
Guido van Rossumad0ee831995-03-01 10:34:45 +00005566#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005567PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005568"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005569Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005570
Barry Warsaw53699e91996-12-10 23:23:01 +00005571static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005572posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005573{
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005575}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005576#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005578
Guido van Rossumad0ee831995-03-01 10:34:45 +00005579#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005580PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005581"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005582Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005583
Barry Warsaw53699e91996-12-10 23:23:01 +00005584static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005585posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005586{
Victor Stinner8c62be82010-05-06 00:08:46 +00005587 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005588}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005589#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005590
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005591
Guido van Rossumad0ee831995-03-01 10:34:45 +00005592#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005593PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005594"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005595Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005596
Barry Warsaw53699e91996-12-10 23:23:01 +00005597static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005598posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005599{
Victor Stinner8c62be82010-05-06 00:08:46 +00005600 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005601}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005602#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005603
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005604
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005605PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005606"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005607Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005608
Barry Warsaw53699e91996-12-10 23:23:01 +00005609static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005610posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005611{
Victor Stinner8c62be82010-05-06 00:08:46 +00005612 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005613}
5614
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005615#ifdef HAVE_GETGROUPLIST
5616PyDoc_STRVAR(posix_getgrouplist__doc__,
5617"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5618Returns a list of groups to which a user belongs.\n\n\
5619 user: username to lookup\n\
5620 group: base group id of the user");
5621
5622static PyObject *
5623posix_getgrouplist(PyObject *self, PyObject *args)
5624{
5625#ifdef NGROUPS_MAX
5626#define MAX_GROUPS NGROUPS_MAX
5627#else
5628 /* defined to be 16 on Solaris7, so this should be a small number */
5629#define MAX_GROUPS 64
5630#endif
5631
5632 const char *user;
5633 int i, ngroups;
5634 PyObject *list;
5635#ifdef __APPLE__
5636 int *groups, basegid;
5637#else
5638 gid_t *groups, basegid;
5639#endif
5640 ngroups = MAX_GROUPS;
5641
5642 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5643 return NULL;
5644
5645#ifdef __APPLE__
5646 groups = PyMem_Malloc(ngroups * sizeof(int));
5647#else
5648 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5649#endif
5650 if (groups == NULL)
5651 return PyErr_NoMemory();
5652
5653 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5654 PyMem_Del(groups);
5655 return posix_error();
5656 }
5657
5658 list = PyList_New(ngroups);
5659 if (list == NULL) {
5660 PyMem_Del(groups);
5661 return NULL;
5662 }
5663
5664 for (i = 0; i < ngroups; i++) {
5665 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5666 if (o == NULL) {
5667 Py_DECREF(list);
5668 PyMem_Del(groups);
5669 return NULL;
5670 }
5671 PyList_SET_ITEM(list, i, o);
5672 }
5673
5674 PyMem_Del(groups);
5675
5676 return list;
5677}
5678#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005679
Fred Drakec9680921999-12-13 16:37:25 +00005680#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005681PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005682"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005683Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005684
5685static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005686posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005687{
5688 PyObject *result = NULL;
5689
Fred Drakec9680921999-12-13 16:37:25 +00005690#ifdef NGROUPS_MAX
5691#define MAX_GROUPS NGROUPS_MAX
5692#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005693 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005694#define MAX_GROUPS 64
5695#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005696 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005697
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005698 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005699 * This is a helper variable to store the intermediate result when
5700 * that happens.
5701 *
5702 * To keep the code readable the OSX behaviour is unconditional,
5703 * according to the POSIX spec this should be safe on all unix-y
5704 * systems.
5705 */
5706 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005707 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005708
Victor Stinner8c62be82010-05-06 00:08:46 +00005709 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005710 if (n < 0) {
5711 if (errno == EINVAL) {
5712 n = getgroups(0, NULL);
5713 if (n == -1) {
5714 return posix_error();
5715 }
5716 if (n == 0) {
5717 /* Avoid malloc(0) */
5718 alt_grouplist = grouplist;
5719 } else {
5720 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5721 if (alt_grouplist == NULL) {
5722 errno = EINVAL;
5723 return posix_error();
5724 }
5725 n = getgroups(n, alt_grouplist);
5726 if (n == -1) {
5727 PyMem_Free(alt_grouplist);
5728 return posix_error();
5729 }
5730 }
5731 } else {
5732 return posix_error();
5733 }
5734 }
5735 result = PyList_New(n);
5736 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005737 int i;
5738 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005739 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005740 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005741 Py_DECREF(result);
5742 result = NULL;
5743 break;
Fred Drakec9680921999-12-13 16:37:25 +00005744 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005745 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005746 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005747 }
5748
5749 if (alt_grouplist != grouplist) {
5750 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005751 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005752
Fred Drakec9680921999-12-13 16:37:25 +00005753 return result;
5754}
5755#endif
5756
Antoine Pitroub7572f02009-12-02 20:46:48 +00005757#ifdef HAVE_INITGROUPS
5758PyDoc_STRVAR(posix_initgroups__doc__,
5759"initgroups(username, gid) -> None\n\n\
5760Call the system initgroups() to initialize the group access list with all of\n\
5761the groups of which the specified username is a member, plus the specified\n\
5762group id.");
5763
5764static PyObject *
5765posix_initgroups(PyObject *self, PyObject *args)
5766{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005767 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005768 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005769 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005770 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005771
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005772 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5773 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005774 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005775 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005776
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005777 res = initgroups(username, (gid_t) gid);
5778 Py_DECREF(oname);
5779 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005780 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005781
Victor Stinner8c62be82010-05-06 00:08:46 +00005782 Py_INCREF(Py_None);
5783 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005784}
5785#endif
5786
Martin v. Löwis606edc12002-06-13 21:09:11 +00005787#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005788PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005789"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005790Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005791
5792static PyObject *
5793posix_getpgid(PyObject *self, PyObject *args)
5794{
Victor Stinner8c62be82010-05-06 00:08:46 +00005795 pid_t pid, pgid;
5796 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5797 return NULL;
5798 pgid = getpgid(pid);
5799 if (pgid < 0)
5800 return posix_error();
5801 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005802}
5803#endif /* HAVE_GETPGID */
5804
5805
Guido van Rossumb6775db1994-08-01 11:34:53 +00005806#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005807PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005808"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005809Return the current process group id.");
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_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005813{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005814#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005815 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005816#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005817 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005818#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005819}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005820#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005821
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005822
Guido van Rossumb6775db1994-08-01 11:34:53 +00005823#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005824PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005825"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005826Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005827
Barry Warsaw53699e91996-12-10 23:23:01 +00005828static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005829posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005830{
Guido van Rossum64933891994-10-20 21:56:42 +00005831#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005832 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005833#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005834 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005835#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005836 return posix_error();
5837 Py_INCREF(Py_None);
5838 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005839}
5840
Guido van Rossumb6775db1994-08-01 11:34:53 +00005841#endif /* HAVE_SETPGRP */
5842
Guido van Rossumad0ee831995-03-01 10:34:45 +00005843#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005844
5845#ifdef MS_WINDOWS
5846#include <tlhelp32.h>
5847
5848static PyObject*
5849win32_getppid()
5850{
5851 HANDLE snapshot;
5852 pid_t mypid;
5853 PyObject* result = NULL;
5854 BOOL have_record;
5855 PROCESSENTRY32 pe;
5856
5857 mypid = getpid(); /* This function never fails */
5858
5859 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5860 if (snapshot == INVALID_HANDLE_VALUE)
5861 return PyErr_SetFromWindowsErr(GetLastError());
5862
5863 pe.dwSize = sizeof(pe);
5864 have_record = Process32First(snapshot, &pe);
5865 while (have_record) {
5866 if (mypid == (pid_t)pe.th32ProcessID) {
5867 /* We could cache the ulong value in a static variable. */
5868 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5869 break;
5870 }
5871
5872 have_record = Process32Next(snapshot, &pe);
5873 }
5874
5875 /* If our loop exits and our pid was not found (result will be NULL)
5876 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5877 * error anyway, so let's raise it. */
5878 if (!result)
5879 result = PyErr_SetFromWindowsErr(GetLastError());
5880
5881 CloseHandle(snapshot);
5882
5883 return result;
5884}
5885#endif /*MS_WINDOWS*/
5886
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005887PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005888"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005889Return the parent's process id. If the parent process has already exited,\n\
5890Windows machines will still return its id; others systems will return the id\n\
5891of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005892
Barry Warsaw53699e91996-12-10 23:23:01 +00005893static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005894posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005895{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005896#ifdef MS_WINDOWS
5897 return win32_getppid();
5898#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005899 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005900#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005901}
5902#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005903
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005904
Fred Drake12c6e2d1999-12-14 21:25:03 +00005905#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005906PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005907"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005908Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005909
5910static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005911posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005912{
Victor Stinner8c62be82010-05-06 00:08:46 +00005913 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005914#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005915 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005916 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005917
5918 if (GetUserNameW(user_name, &num_chars)) {
5919 /* num_chars is the number of unicode chars plus null terminator */
5920 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005921 }
5922 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005923 result = PyErr_SetFromWindowsErr(GetLastError());
5924#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 char *name;
5926 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005927
Victor Stinner8c62be82010-05-06 00:08:46 +00005928 errno = 0;
5929 name = getlogin();
5930 if (name == NULL) {
5931 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005932 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005933 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005934 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 }
5936 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005937 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005938 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005939#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005940 return result;
5941}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005942#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005943
Guido van Rossumad0ee831995-03-01 10:34:45 +00005944#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005945PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005946"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005947Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005948
Barry Warsaw53699e91996-12-10 23:23:01 +00005949static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005950posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005951{
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005953}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005954#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005956
Guido van Rossumad0ee831995-03-01 10:34:45 +00005957#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005958PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005959"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005960Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005961
Barry Warsaw53699e91996-12-10 23:23:01 +00005962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005963posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005964{
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 pid_t pid;
5966 int sig;
5967 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5968 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005969 if (kill(pid, sig) == -1)
5970 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00005971 Py_INCREF(Py_None);
5972 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005973}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005974#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005975
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005976#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005977PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005978"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005979Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005980
5981static PyObject *
5982posix_killpg(PyObject *self, PyObject *args)
5983{
Victor Stinner8c62be82010-05-06 00:08:46 +00005984 int sig;
5985 pid_t pgid;
5986 /* XXX some man pages make the `pgid` parameter an int, others
5987 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5988 take the same type. Moreover, pid_t is always at least as wide as
5989 int (else compilation of this module fails), which is safe. */
5990 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5991 return NULL;
5992 if (killpg(pgid, sig) == -1)
5993 return posix_error();
5994 Py_INCREF(Py_None);
5995 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005996}
5997#endif
5998
Brian Curtineb24d742010-04-12 17:16:38 +00005999#ifdef MS_WINDOWS
6000PyDoc_STRVAR(win32_kill__doc__,
6001"kill(pid, sig)\n\n\
6002Kill a process with a signal.");
6003
6004static PyObject *
6005win32_kill(PyObject *self, PyObject *args)
6006{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006007 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006008 DWORD pid, sig, err;
6009 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006010
Victor Stinner8c62be82010-05-06 00:08:46 +00006011 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6012 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006013
Victor Stinner8c62be82010-05-06 00:08:46 +00006014 /* Console processes which share a common console can be sent CTRL+C or
6015 CTRL+BREAK events, provided they handle said events. */
6016 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6017 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6018 err = GetLastError();
6019 PyErr_SetFromWindowsErr(err);
6020 }
6021 else
6022 Py_RETURN_NONE;
6023 }
Brian Curtineb24d742010-04-12 17:16:38 +00006024
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6026 attempt to open and terminate the process. */
6027 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6028 if (handle == NULL) {
6029 err = GetLastError();
6030 return PyErr_SetFromWindowsErr(err);
6031 }
Brian Curtineb24d742010-04-12 17:16:38 +00006032
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 if (TerminateProcess(handle, sig) == 0) {
6034 err = GetLastError();
6035 result = PyErr_SetFromWindowsErr(err);
6036 } else {
6037 Py_INCREF(Py_None);
6038 result = Py_None;
6039 }
Brian Curtineb24d742010-04-12 17:16:38 +00006040
Victor Stinner8c62be82010-05-06 00:08:46 +00006041 CloseHandle(handle);
6042 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006043}
6044#endif /* MS_WINDOWS */
6045
Guido van Rossumc0125471996-06-28 18:55:32 +00006046#ifdef HAVE_PLOCK
6047
6048#ifdef HAVE_SYS_LOCK_H
6049#include <sys/lock.h>
6050#endif
6051
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006052PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006053"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006054Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006055
Barry Warsaw53699e91996-12-10 23:23:01 +00006056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006057posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006058{
Victor Stinner8c62be82010-05-06 00:08:46 +00006059 int op;
6060 if (!PyArg_ParseTuple(args, "i:plock", &op))
6061 return NULL;
6062 if (plock(op) == -1)
6063 return posix_error();
6064 Py_INCREF(Py_None);
6065 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006066}
6067#endif
6068
Guido van Rossumb6775db1994-08-01 11:34:53 +00006069#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006070PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006071"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006072Set the current process's user id.");
6073
Barry Warsaw53699e91996-12-10 23:23:01 +00006074static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006075posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006076{
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 long uid_arg;
6078 uid_t uid;
6079 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6080 return NULL;
6081 uid = uid_arg;
6082 if (uid != uid_arg) {
6083 PyErr_SetString(PyExc_OverflowError, "user id too big");
6084 return NULL;
6085 }
6086 if (setuid(uid) < 0)
6087 return posix_error();
6088 Py_INCREF(Py_None);
6089 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006090}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006091#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006093
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006094#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006095PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006096"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097Set the current process's effective user id.");
6098
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006099static PyObject *
6100posix_seteuid (PyObject *self, PyObject *args)
6101{
Victor Stinner8c62be82010-05-06 00:08:46 +00006102 long euid_arg;
6103 uid_t euid;
6104 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6105 return NULL;
6106 euid = euid_arg;
6107 if (euid != euid_arg) {
6108 PyErr_SetString(PyExc_OverflowError, "user id too big");
6109 return NULL;
6110 }
6111 if (seteuid(euid) < 0) {
6112 return posix_error();
6113 } else {
6114 Py_INCREF(Py_None);
6115 return Py_None;
6116 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006117}
6118#endif /* HAVE_SETEUID */
6119
6120#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006122"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123Set the current process's effective group id.");
6124
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006125static PyObject *
6126posix_setegid (PyObject *self, PyObject *args)
6127{
Victor Stinner8c62be82010-05-06 00:08:46 +00006128 long egid_arg;
6129 gid_t egid;
6130 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6131 return NULL;
6132 egid = egid_arg;
6133 if (egid != egid_arg) {
6134 PyErr_SetString(PyExc_OverflowError, "group id too big");
6135 return NULL;
6136 }
6137 if (setegid(egid) < 0) {
6138 return posix_error();
6139 } else {
6140 Py_INCREF(Py_None);
6141 return Py_None;
6142 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006143}
6144#endif /* HAVE_SETEGID */
6145
6146#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006147PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006148"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006149Set the current process's real and effective user ids.");
6150
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006151static PyObject *
6152posix_setreuid (PyObject *self, PyObject *args)
6153{
Victor Stinner8c62be82010-05-06 00:08:46 +00006154 long ruid_arg, euid_arg;
6155 uid_t ruid, euid;
6156 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6157 return NULL;
6158 if (ruid_arg == -1)
6159 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6160 else
6161 ruid = ruid_arg; /* otherwise, assign from our long */
6162 if (euid_arg == -1)
6163 euid = (uid_t)-1;
6164 else
6165 euid = euid_arg;
6166 if ((euid_arg != -1 && euid != euid_arg) ||
6167 (ruid_arg != -1 && ruid != ruid_arg)) {
6168 PyErr_SetString(PyExc_OverflowError, "user id too big");
6169 return NULL;
6170 }
6171 if (setreuid(ruid, euid) < 0) {
6172 return posix_error();
6173 } else {
6174 Py_INCREF(Py_None);
6175 return Py_None;
6176 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006177}
6178#endif /* HAVE_SETREUID */
6179
6180#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006181PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006182"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006183Set the current process's real and effective group ids.");
6184
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006185static PyObject *
6186posix_setregid (PyObject *self, PyObject *args)
6187{
Victor Stinner8c62be82010-05-06 00:08:46 +00006188 long rgid_arg, egid_arg;
6189 gid_t rgid, egid;
6190 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6191 return NULL;
6192 if (rgid_arg == -1)
6193 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6194 else
6195 rgid = rgid_arg; /* otherwise, assign from our long */
6196 if (egid_arg == -1)
6197 egid = (gid_t)-1;
6198 else
6199 egid = egid_arg;
6200 if ((egid_arg != -1 && egid != egid_arg) ||
6201 (rgid_arg != -1 && rgid != rgid_arg)) {
6202 PyErr_SetString(PyExc_OverflowError, "group id too big");
6203 return NULL;
6204 }
6205 if (setregid(rgid, egid) < 0) {
6206 return posix_error();
6207 } else {
6208 Py_INCREF(Py_None);
6209 return Py_None;
6210 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006211}
6212#endif /* HAVE_SETREGID */
6213
Guido van Rossumb6775db1994-08-01 11:34:53 +00006214#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006215PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006216"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006217Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006218
Barry Warsaw53699e91996-12-10 23:23:01 +00006219static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006220posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006221{
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 long gid_arg;
6223 gid_t gid;
6224 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6225 return NULL;
6226 gid = gid_arg;
6227 if (gid != gid_arg) {
6228 PyErr_SetString(PyExc_OverflowError, "group id too big");
6229 return NULL;
6230 }
6231 if (setgid(gid) < 0)
6232 return posix_error();
6233 Py_INCREF(Py_None);
6234 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006235}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006236#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006237
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006238#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006239PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006240"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006241Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006242
6243static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006244posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006245{
Victor Stinner8c62be82010-05-06 00:08:46 +00006246 int i, len;
6247 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006248
Victor Stinner8c62be82010-05-06 00:08:46 +00006249 if (!PySequence_Check(groups)) {
6250 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6251 return NULL;
6252 }
6253 len = PySequence_Size(groups);
6254 if (len > MAX_GROUPS) {
6255 PyErr_SetString(PyExc_ValueError, "too many groups");
6256 return NULL;
6257 }
6258 for(i = 0; i < len; i++) {
6259 PyObject *elem;
6260 elem = PySequence_GetItem(groups, i);
6261 if (!elem)
6262 return NULL;
6263 if (!PyLong_Check(elem)) {
6264 PyErr_SetString(PyExc_TypeError,
6265 "groups must be integers");
6266 Py_DECREF(elem);
6267 return NULL;
6268 } else {
6269 unsigned long x = PyLong_AsUnsignedLong(elem);
6270 if (PyErr_Occurred()) {
6271 PyErr_SetString(PyExc_TypeError,
6272 "group id too big");
6273 Py_DECREF(elem);
6274 return NULL;
6275 }
6276 grouplist[i] = x;
6277 /* read back the value to see if it fitted in gid_t */
6278 if (grouplist[i] != x) {
6279 PyErr_SetString(PyExc_TypeError,
6280 "group id too big");
6281 Py_DECREF(elem);
6282 return NULL;
6283 }
6284 }
6285 Py_DECREF(elem);
6286 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006287
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 if (setgroups(len, grouplist) < 0)
6289 return posix_error();
6290 Py_INCREF(Py_None);
6291 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006292}
6293#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006294
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006295#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6296static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006297wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006298{
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 PyObject *result;
6300 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006301 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006302
Victor Stinner8c62be82010-05-06 00:08:46 +00006303 if (pid == -1)
6304 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006305
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 if (struct_rusage == NULL) {
6307 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6308 if (m == NULL)
6309 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006310 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006311 Py_DECREF(m);
6312 if (struct_rusage == NULL)
6313 return NULL;
6314 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006315
Victor Stinner8c62be82010-05-06 00:08:46 +00006316 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6317 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6318 if (!result)
6319 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006320
6321#ifndef doubletime
6322#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6323#endif
6324
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006326 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006327 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006328 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006329#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006330 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6331 SET_INT(result, 2, ru->ru_maxrss);
6332 SET_INT(result, 3, ru->ru_ixrss);
6333 SET_INT(result, 4, ru->ru_idrss);
6334 SET_INT(result, 5, ru->ru_isrss);
6335 SET_INT(result, 6, ru->ru_minflt);
6336 SET_INT(result, 7, ru->ru_majflt);
6337 SET_INT(result, 8, ru->ru_nswap);
6338 SET_INT(result, 9, ru->ru_inblock);
6339 SET_INT(result, 10, ru->ru_oublock);
6340 SET_INT(result, 11, ru->ru_msgsnd);
6341 SET_INT(result, 12, ru->ru_msgrcv);
6342 SET_INT(result, 13, ru->ru_nsignals);
6343 SET_INT(result, 14, ru->ru_nvcsw);
6344 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006345#undef SET_INT
6346
Victor Stinner8c62be82010-05-06 00:08:46 +00006347 if (PyErr_Occurred()) {
6348 Py_DECREF(result);
6349 return NULL;
6350 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006351
Victor Stinner8c62be82010-05-06 00:08:46 +00006352 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006353}
6354#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6355
6356#ifdef HAVE_WAIT3
6357PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006358"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006359Wait for completion of a child process.");
6360
6361static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006362posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006363{
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 pid_t pid;
6365 int options;
6366 struct rusage ru;
6367 WAIT_TYPE status;
6368 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006369
Victor Stinner4195b5c2012-02-08 23:03:19 +01006370 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006372
Victor Stinner8c62be82010-05-06 00:08:46 +00006373 Py_BEGIN_ALLOW_THREADS
6374 pid = wait3(&status, options, &ru);
6375 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006376
Victor Stinner4195b5c2012-02-08 23:03:19 +01006377 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006378}
6379#endif /* HAVE_WAIT3 */
6380
6381#ifdef HAVE_WAIT4
6382PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006383"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006384Wait for completion of a given child process.");
6385
6386static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006387posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006388{
Victor Stinner8c62be82010-05-06 00:08:46 +00006389 pid_t pid;
6390 int options;
6391 struct rusage ru;
6392 WAIT_TYPE status;
6393 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006394
Victor Stinner4195b5c2012-02-08 23:03:19 +01006395 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006397
Victor Stinner8c62be82010-05-06 00:08:46 +00006398 Py_BEGIN_ALLOW_THREADS
6399 pid = wait4(pid, &status, options, &ru);
6400 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006401
Victor Stinner4195b5c2012-02-08 23:03:19 +01006402 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006403}
6404#endif /* HAVE_WAIT4 */
6405
Ross Lagerwall7807c352011-03-17 20:20:30 +02006406#if defined(HAVE_WAITID) && !defined(__APPLE__)
6407PyDoc_STRVAR(posix_waitid__doc__,
6408"waitid(idtype, id, options) -> waitid_result\n\n\
6409Wait for the completion of one or more child processes.\n\n\
6410idtype can be P_PID, P_PGID or P_ALL.\n\
6411id specifies the pid to wait on.\n\
6412options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6413or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6414Returns either waitid_result or None if WNOHANG is specified and there are\n\
6415no children in a waitable state.");
6416
6417static PyObject *
6418posix_waitid(PyObject *self, PyObject *args)
6419{
6420 PyObject *result;
6421 idtype_t idtype;
6422 id_t id;
6423 int options, res;
6424 siginfo_t si;
6425 si.si_pid = 0;
6426 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6427 return NULL;
6428 Py_BEGIN_ALLOW_THREADS
6429 res = waitid(idtype, id, &si, options);
6430 Py_END_ALLOW_THREADS
6431 if (res == -1)
6432 return posix_error();
6433
6434 if (si.si_pid == 0)
6435 Py_RETURN_NONE;
6436
6437 result = PyStructSequence_New(&WaitidResultType);
6438 if (!result)
6439 return NULL;
6440
6441 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6442 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6443 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6444 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6445 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6446 if (PyErr_Occurred()) {
6447 Py_DECREF(result);
6448 return NULL;
6449 }
6450
6451 return result;
6452}
6453#endif
6454
Guido van Rossumb6775db1994-08-01 11:34:53 +00006455#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006456PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006457"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006458Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006459
Barry Warsaw53699e91996-12-10 23:23:01 +00006460static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006461posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006462{
Victor Stinner8c62be82010-05-06 00:08:46 +00006463 pid_t pid;
6464 int options;
6465 WAIT_TYPE status;
6466 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006467
Victor Stinner8c62be82010-05-06 00:08:46 +00006468 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6469 return NULL;
6470 Py_BEGIN_ALLOW_THREADS
6471 pid = waitpid(pid, &status, options);
6472 Py_END_ALLOW_THREADS
6473 if (pid == -1)
6474 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006475
Victor Stinner8c62be82010-05-06 00:08:46 +00006476 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006477}
6478
Tim Petersab034fa2002-02-01 11:27:43 +00006479#elif defined(HAVE_CWAIT)
6480
6481/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006482PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006483"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006484"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006485
6486static PyObject *
6487posix_waitpid(PyObject *self, PyObject *args)
6488{
Victor Stinner8c62be82010-05-06 00:08:46 +00006489 Py_intptr_t pid;
6490 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006491
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6493 return NULL;
6494 Py_BEGIN_ALLOW_THREADS
6495 pid = _cwait(&status, pid, options);
6496 Py_END_ALLOW_THREADS
6497 if (pid == -1)
6498 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006499
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 /* shift the status left a byte so this is more like the POSIX waitpid */
6501 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006502}
6503#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006504
Guido van Rossumad0ee831995-03-01 10:34:45 +00006505#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006506PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006507"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006508Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006509
Barry Warsaw53699e91996-12-10 23:23:01 +00006510static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006511posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006512{
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 pid_t pid;
6514 WAIT_TYPE status;
6515 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006516
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 Py_BEGIN_ALLOW_THREADS
6518 pid = wait(&status);
6519 Py_END_ALLOW_THREADS
6520 if (pid == -1)
6521 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006522
Victor Stinner8c62be82010-05-06 00:08:46 +00006523 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006524}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006525#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006527
Larry Hastings9cf065c2012-06-22 16:30:09 -07006528#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6529PyDoc_STRVAR(readlink__doc__,
6530"readlink(path, *, dir_fd=None) -> path\n\n\
6531Return a string representing the path to which the symbolic link points.\n\
6532\n\
6533If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6534 and path should be relative; path will then be relative to that directory.\n\
6535dir_fd may not be implemented on your platform.\n\
6536 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006537#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006538
Guido van Rossumb6775db1994-08-01 11:34:53 +00006539#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006540
Barry Warsaw53699e91996-12-10 23:23:01 +00006541static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006542posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006543{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006544 path_t path;
6545 int dir_fd = DEFAULT_DIR_FD;
6546 char buffer[MAXPATHLEN];
6547 ssize_t length;
6548 PyObject *return_value = NULL;
6549 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006550
Larry Hastings9cf065c2012-06-22 16:30:09 -07006551 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006552 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006553 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6554 path_converter, &path,
6555#ifdef HAVE_READLINKAT
6556 dir_fd_converter, &dir_fd
6557#else
6558 dir_fd_unavailable, &dir_fd
6559#endif
6560 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006562
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006564#ifdef HAVE_READLINKAT
6565 if (dir_fd != DEFAULT_DIR_FD)
6566 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006567 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006568#endif
6569 length = readlink(path.narrow, buffer, sizeof(buffer));
6570 Py_END_ALLOW_THREADS
6571
6572 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006573 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006574 goto exit;
6575 }
6576
6577 if (PyUnicode_Check(path.object))
6578 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6579 else
6580 return_value = PyBytes_FromStringAndSize(buffer, length);
6581exit:
6582 path_cleanup(&path);
6583 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006584}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006585
6586
Guido van Rossumb6775db1994-08-01 11:34:53 +00006587#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006588
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006589
Larry Hastings9cf065c2012-06-22 16:30:09 -07006590#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006591PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006592"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
6593Create a symbolic link pointing to src named dst.\n\n\
6594target_is_directory is required on Windows if the target is to be\n\
6595 interpreted as a directory. (On Windows, symlink requires\n\
6596 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
6597 target_is_directory is ignored on non-Windows platforms.\n\
6598\n\
6599If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6600 and path should be relative; path will then be relative to that directory.\n\
6601dir_fd may not be implemented on your platform.\n\
6602 If it is unavailable, using it will raise a NotImplementedError.");
6603
6604#if defined(MS_WINDOWS)
6605
6606/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6607static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
6608static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
6609static int
6610check_CreateSymbolicLink()
6611{
6612 HINSTANCE hKernel32;
6613 /* only recheck */
6614 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
6615 return 1;
6616 hKernel32 = GetModuleHandleW(L"KERNEL32");
6617 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6618 "CreateSymbolicLinkW");
6619 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
6620 "CreateSymbolicLinkA");
6621 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
6622}
6623
6624#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006625
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006626static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006627posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006628{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006629 path_t src;
6630 path_t dst;
6631 int dir_fd = DEFAULT_DIR_FD;
6632 int target_is_directory = 0;
6633 static char *keywords[] = {"src", "dst", "target_is_directory",
6634 "dir_fd", NULL};
6635 PyObject *return_value;
6636#ifdef MS_WINDOWS
6637 DWORD result;
6638#else
6639 int result;
6640#endif
6641
6642 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01006643 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006644 src.argument_name = "src";
6645 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01006646 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006647 dst.argument_name = "dst";
6648
6649#ifdef MS_WINDOWS
6650 if (!check_CreateSymbolicLink()) {
6651 PyErr_SetString(PyExc_NotImplementedError,
6652 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006653 return NULL;
6654 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006655 if (!win32_can_symlink) {
6656 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006657 return NULL;
6658 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006659#endif
6660
6661 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
6662 keywords,
6663 path_converter, &src,
6664 path_converter, &dst,
6665 &target_is_directory,
6666#ifdef HAVE_SYMLINKAT
6667 dir_fd_converter, &dir_fd
6668#else
6669 dir_fd_unavailable, &dir_fd
6670#endif
6671 ))
6672 return NULL;
6673
6674 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
6675 PyErr_SetString(PyExc_ValueError,
6676 "symlink: src and dst must be the same type");
6677 return_value = NULL;
6678 goto exit;
6679 }
6680
6681#ifdef MS_WINDOWS
6682 Py_BEGIN_ALLOW_THREADS
6683 if (dst.wide)
6684 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
6685 target_is_directory);
6686 else
6687 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
6688 target_is_directory);
6689 Py_END_ALLOW_THREADS
6690
6691 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01006692 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006693 goto exit;
6694 }
6695
6696#else
6697
6698 Py_BEGIN_ALLOW_THREADS
6699#if HAVE_SYMLINKAT
6700 if (dir_fd != DEFAULT_DIR_FD)
6701 result = symlinkat(src.narrow, dir_fd, dst.narrow);
6702 else
6703#endif
6704 result = symlink(src.narrow, dst.narrow);
6705 Py_END_ALLOW_THREADS
6706
6707 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01006708 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006709 goto exit;
6710 }
6711#endif
6712
6713 return_value = Py_None;
6714 Py_INCREF(Py_None);
6715 goto exit; /* silence "unused label" warning */
6716exit:
6717 path_cleanup(&src);
6718 path_cleanup(&dst);
6719 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006720}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006721
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006722#endif /* HAVE_SYMLINK */
6723
Larry Hastings9cf065c2012-06-22 16:30:09 -07006724
Brian Curtind40e6f72010-07-08 21:39:08 +00006725#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6726
Brian Curtind40e6f72010-07-08 21:39:08 +00006727static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006728win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00006729{
6730 wchar_t *path;
6731 DWORD n_bytes_returned;
6732 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006733 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006734 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00006735 HANDLE reparse_point_handle;
6736
6737 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6738 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6739 wchar_t *print_name;
6740
Larry Hastings9cf065c2012-06-22 16:30:09 -07006741 static char *keywords[] = {"path", "dir_fd", NULL};
6742
6743 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
6744 &po,
6745 dir_fd_unavailable, &dir_fd
6746 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02006747 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006748
Victor Stinnereb5657a2011-09-30 01:44:27 +02006749 path = PyUnicode_AsUnicode(po);
6750 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006751 return NULL;
6752
6753 /* First get a handle to the reparse point */
6754 Py_BEGIN_ALLOW_THREADS
6755 reparse_point_handle = CreateFileW(
6756 path,
6757 0,
6758 0,
6759 0,
6760 OPEN_EXISTING,
6761 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6762 0);
6763 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006764
Brian Curtind40e6f72010-07-08 21:39:08 +00006765 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006766 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006767
Brian Curtind40e6f72010-07-08 21:39:08 +00006768 Py_BEGIN_ALLOW_THREADS
6769 /* New call DeviceIoControl to read the reparse point */
6770 io_result = DeviceIoControl(
6771 reparse_point_handle,
6772 FSCTL_GET_REPARSE_POINT,
6773 0, 0, /* in buffer */
6774 target_buffer, sizeof(target_buffer),
6775 &n_bytes_returned,
6776 0 /* we're not using OVERLAPPED_IO */
6777 );
6778 CloseHandle(reparse_point_handle);
6779 Py_END_ALLOW_THREADS
6780
6781 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006782 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006783
6784 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6785 {
6786 PyErr_SetString(PyExc_ValueError,
6787 "not a symbolic link");
6788 return NULL;
6789 }
Brian Curtin74e45612010-07-09 15:58:59 +00006790 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6791 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6792
6793 result = PyUnicode_FromWideChar(print_name,
6794 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006795 return result;
6796}
6797
6798#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6799
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006800
Larry Hastings605a62d2012-06-24 04:33:36 -07006801static PyStructSequence_Field times_result_fields[] = {
6802 {"user", "user time"},
6803 {"system", "system time"},
6804 {"children_user", "user time of children"},
6805 {"children_system", "system time of children"},
6806 {"elapsed", "elapsed time since an arbitrary point in the past"},
6807 {NULL}
6808};
6809
6810PyDoc_STRVAR(times_result__doc__,
6811"times_result: Result from os.times().\n\n\
6812This object may be accessed either as a tuple of\n\
6813 (user, system, children_user, children_system, elapsed),\n\
6814or via the attributes user, system, children_user, children_system,\n\
6815and elapsed.\n\
6816\n\
6817See os.times for more information.");
6818
6819static PyStructSequence_Desc times_result_desc = {
6820 "times_result", /* name */
6821 times_result__doc__, /* doc */
6822 times_result_fields,
6823 5
6824};
6825
6826static PyTypeObject TimesResultType;
6827
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006828#ifdef MS_WINDOWS
6829#define HAVE_TIMES /* mandatory, for the method table */
6830#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07006831
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006832#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07006833
6834static PyObject *
6835build_times_result(double user, double system,
6836 double children_user, double children_system,
6837 double elapsed)
6838{
6839 PyObject *value = PyStructSequence_New(&TimesResultType);
6840 if (value == NULL)
6841 return NULL;
6842
6843#define SET(i, field) \
6844 { \
6845 PyObject *o = PyFloat_FromDouble(field); \
6846 if (!o) { \
6847 Py_DECREF(value); \
6848 return NULL; \
6849 } \
6850 PyStructSequence_SET_ITEM(value, i, o); \
6851 } \
6852
6853 SET(0, user);
6854 SET(1, system);
6855 SET(2, children_user);
6856 SET(3, children_system);
6857 SET(4, elapsed);
6858
6859#undef SET
6860
6861 return value;
6862}
6863
6864PyDoc_STRVAR(posix_times__doc__,
6865"times() -> times_result\n\n\
6866Return an object containing floating point numbers indicating process\n\
6867times. The object behaves like a named tuple with these fields:\n\
6868 (utime, stime, cutime, cstime, elapsed_time)");
6869
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006870#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00006871static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006872posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006873{
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 FILETIME create, exit, kernel, user;
6875 HANDLE hProc;
6876 hProc = GetCurrentProcess();
6877 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6878 /* The fields of a FILETIME structure are the hi and lo part
6879 of a 64-bit value expressed in 100 nanosecond units.
6880 1e7 is one second in such units; 1e-7 the inverse.
6881 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6882 */
Larry Hastings605a62d2012-06-24 04:33:36 -07006883 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 (double)(user.dwHighDateTime*429.4967296 +
6885 user.dwLowDateTime*1e-7),
6886 (double)(kernel.dwHighDateTime*429.4967296 +
6887 kernel.dwLowDateTime*1e-7),
6888 (double)0,
6889 (double)0,
6890 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006891}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006892#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006893#define NEED_TICKS_PER_SECOND
6894static long ticks_per_second = -1;
6895static PyObject *
6896posix_times(PyObject *self, PyObject *noargs)
6897{
6898 struct tms t;
6899 clock_t c;
6900 errno = 0;
6901 c = times(&t);
6902 if (c == (clock_t) -1)
6903 return posix_error();
6904 return build_times_result(
6905 (double)t.tms_utime / ticks_per_second,
6906 (double)t.tms_stime / ticks_per_second,
6907 (double)t.tms_cutime / ticks_per_second,
6908 (double)t.tms_cstime / ticks_per_second,
6909 (double)c / ticks_per_second);
6910}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006911#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006912
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006913#endif /* HAVE_TIMES */
6914
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006915
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006916#ifdef HAVE_GETSID
6917PyDoc_STRVAR(posix_getsid__doc__,
6918"getsid(pid) -> sid\n\n\
6919Call the system call getsid().");
6920
6921static PyObject *
6922posix_getsid(PyObject *self, PyObject *args)
6923{
Victor Stinner8c62be82010-05-06 00:08:46 +00006924 pid_t pid;
6925 int sid;
6926 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6927 return NULL;
6928 sid = getsid(pid);
6929 if (sid < 0)
6930 return posix_error();
6931 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006932}
6933#endif /* HAVE_GETSID */
6934
6935
Guido van Rossumb6775db1994-08-01 11:34:53 +00006936#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006937PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006938"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006939Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006940
Barry Warsaw53699e91996-12-10 23:23:01 +00006941static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006942posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006943{
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 if (setsid() < 0)
6945 return posix_error();
6946 Py_INCREF(Py_None);
6947 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006948}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006949#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006950
Guido van Rossumb6775db1994-08-01 11:34:53 +00006951#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006952PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006953"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006954Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006955
Barry Warsaw53699e91996-12-10 23:23:01 +00006956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006957posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006958{
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 pid_t pid;
6960 int pgrp;
6961 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6962 return NULL;
6963 if (setpgid(pid, pgrp) < 0)
6964 return posix_error();
6965 Py_INCREF(Py_None);
6966 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006967}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006968#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006970
Guido van Rossumb6775db1994-08-01 11:34:53 +00006971#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006972PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006973"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006974Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006975
Barry Warsaw53699e91996-12-10 23:23:01 +00006976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006977posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006978{
Victor Stinner8c62be82010-05-06 00:08:46 +00006979 int fd;
6980 pid_t pgid;
6981 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6982 return NULL;
6983 pgid = tcgetpgrp(fd);
6984 if (pgid < 0)
6985 return posix_error();
6986 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006987}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006988#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006989
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006990
Guido van Rossumb6775db1994-08-01 11:34:53 +00006991#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006992PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006993"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006994Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006995
Barry Warsaw53699e91996-12-10 23:23:01 +00006996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006997posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006998{
Victor Stinner8c62be82010-05-06 00:08:46 +00006999 int fd;
7000 pid_t pgid;
7001 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7002 return NULL;
7003 if (tcsetpgrp(fd, pgid) < 0)
7004 return posix_error();
7005 Py_INCREF(Py_None);
7006 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007007}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007008#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007009
Guido van Rossum687dd131993-05-17 08:34:16 +00007010/* Functions acting on file descriptors */
7011
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007012PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007013"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7014Open a file for low level IO. Returns a file handle (integer).\n\
7015\n\
7016If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7017 and path should be relative; path will then be relative to that directory.\n\
7018dir_fd may not be implemented on your platform.\n\
7019 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007020
Barry Warsaw53699e91996-12-10 23:23:01 +00007021static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007022posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007023{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007024 path_t path;
7025 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007027 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007029 PyObject *return_value = NULL;
7030 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007031
Larry Hastings9cf065c2012-06-22 16:30:09 -07007032 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007033 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007034 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7035 path_converter, &path,
7036 &flags, &mode,
7037#ifdef HAVE_OPENAT
7038 dir_fd_converter, &dir_fd
7039#else
7040 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007041#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007042 ))
7043 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007044
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007046#ifdef MS_WINDOWS
7047 if (path.wide)
7048 fd = _wopen(path.wide, flags, mode);
7049 else
7050#endif
7051#ifdef HAVE_OPENAT
7052 if (dir_fd != DEFAULT_DIR_FD)
7053 fd = openat(dir_fd, path.narrow, flags, mode);
7054 else
7055#endif
7056 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007058
Larry Hastings9cf065c2012-06-22 16:30:09 -07007059 if (fd == -1) {
Victor Stinner292c8352012-10-30 02:17:38 +01007060 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007061 goto exit;
7062 }
7063
7064 return_value = PyLong_FromLong((long)fd);
7065
7066exit:
7067 path_cleanup(&path);
7068 return return_value;
7069}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007070
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007071PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007072"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007073Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007074
Barry Warsaw53699e91996-12-10 23:23:01 +00007075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007076posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007077{
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 int fd, res;
7079 if (!PyArg_ParseTuple(args, "i:close", &fd))
7080 return NULL;
7081 if (!_PyVerify_fd(fd))
7082 return posix_error();
7083 Py_BEGIN_ALLOW_THREADS
7084 res = close(fd);
7085 Py_END_ALLOW_THREADS
7086 if (res < 0)
7087 return posix_error();
7088 Py_INCREF(Py_None);
7089 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007090}
7091
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007092
Victor Stinner8c62be82010-05-06 00:08:46 +00007093PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007094"closerange(fd_low, fd_high)\n\n\
7095Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7096
7097static PyObject *
7098posix_closerange(PyObject *self, PyObject *args)
7099{
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 int fd_from, fd_to, i;
7101 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7102 return NULL;
7103 Py_BEGIN_ALLOW_THREADS
7104 for (i = fd_from; i < fd_to; i++)
7105 if (_PyVerify_fd(i))
7106 close(i);
7107 Py_END_ALLOW_THREADS
7108 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007109}
7110
7111
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007112PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007113"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007114Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007115
Barry Warsaw53699e91996-12-10 23:23:01 +00007116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007117posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007118{
Victor Stinner8c62be82010-05-06 00:08:46 +00007119 int fd;
7120 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7121 return NULL;
7122 if (!_PyVerify_fd(fd))
7123 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007124 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007125 if (fd < 0)
7126 return posix_error();
7127 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007128}
7129
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007130
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007131PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007132"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007133Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007134
Barry Warsaw53699e91996-12-10 23:23:01 +00007135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007136posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007137{
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 int fd, fd2, res;
7139 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7140 return NULL;
7141 if (!_PyVerify_fd_dup2(fd, fd2))
7142 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007143 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 if (res < 0)
7145 return posix_error();
7146 Py_INCREF(Py_None);
7147 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007148}
7149
Ross Lagerwall7807c352011-03-17 20:20:30 +02007150#ifdef HAVE_LOCKF
7151PyDoc_STRVAR(posix_lockf__doc__,
7152"lockf(fd, cmd, len)\n\n\
7153Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7154fd is an open file descriptor.\n\
7155cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7156F_TEST.\n\
7157len specifies the section of the file to lock.");
7158
7159static PyObject *
7160posix_lockf(PyObject *self, PyObject *args)
7161{
7162 int fd, cmd, res;
7163 off_t len;
7164 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7165 &fd, &cmd, _parse_off_t, &len))
7166 return NULL;
7167
7168 Py_BEGIN_ALLOW_THREADS
7169 res = lockf(fd, cmd, len);
7170 Py_END_ALLOW_THREADS
7171
7172 if (res < 0)
7173 return posix_error();
7174
7175 Py_RETURN_NONE;
7176}
7177#endif
7178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007179
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007180PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007181"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007182Set the current position of a file descriptor.\n\
7183Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007184
Barry Warsaw53699e91996-12-10 23:23:01 +00007185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007186posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007187{
Victor Stinner8c62be82010-05-06 00:08:46 +00007188 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007189#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007190 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007191#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007193#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007194 PyObject *posobj;
7195 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007196 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007197#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7199 switch (how) {
7200 case 0: how = SEEK_SET; break;
7201 case 1: how = SEEK_CUR; break;
7202 case 2: how = SEEK_END; break;
7203 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007204#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007205
Ross Lagerwall8e749672011-03-17 21:54:07 +02007206#if !defined(HAVE_LARGEFILE_SUPPORT)
7207 pos = PyLong_AsLong(posobj);
7208#else
7209 pos = PyLong_AsLongLong(posobj);
7210#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007211 if (PyErr_Occurred())
7212 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007213
Victor Stinner8c62be82010-05-06 00:08:46 +00007214 if (!_PyVerify_fd(fd))
7215 return posix_error();
7216 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007217#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007218 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007219#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007220 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007221#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007222 Py_END_ALLOW_THREADS
7223 if (res < 0)
7224 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007225
7226#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007227 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007228#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007229 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007230#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007231}
7232
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007233
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007234PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007235"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007236Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007237
Barry Warsaw53699e91996-12-10 23:23:01 +00007238static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007239posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007240{
Victor Stinner8c62be82010-05-06 00:08:46 +00007241 int fd, size;
7242 Py_ssize_t n;
7243 PyObject *buffer;
7244 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7245 return NULL;
7246 if (size < 0) {
7247 errno = EINVAL;
7248 return posix_error();
7249 }
7250 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7251 if (buffer == NULL)
7252 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007253 if (!_PyVerify_fd(fd)) {
7254 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007256 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007257 Py_BEGIN_ALLOW_THREADS
7258 n = read(fd, PyBytes_AS_STRING(buffer), size);
7259 Py_END_ALLOW_THREADS
7260 if (n < 0) {
7261 Py_DECREF(buffer);
7262 return posix_error();
7263 }
7264 if (n != size)
7265 _PyBytes_Resize(&buffer, n);
7266 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007267}
7268
Ross Lagerwall7807c352011-03-17 20:20:30 +02007269#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7270 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007271static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007272iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7273{
7274 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007275 Py_ssize_t blen, total = 0;
7276
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007277 *iov = PyMem_New(struct iovec, cnt);
7278 if (*iov == NULL) {
7279 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007280 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007281 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007282
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007283 *buf = PyMem_New(Py_buffer, cnt);
7284 if (*buf == NULL) {
7285 PyMem_Del(*iov);
7286 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007287 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007288 }
7289
7290 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007291 PyObject *item = PySequence_GetItem(seq, i);
7292 if (item == NULL)
7293 goto fail;
7294 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7295 Py_DECREF(item);
7296 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007297 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007298 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007299 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007300 blen = (*buf)[i].len;
7301 (*iov)[i].iov_len = blen;
7302 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007303 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007304 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007305
7306fail:
7307 PyMem_Del(*iov);
7308 for (j = 0; j < i; j++) {
7309 PyBuffer_Release(&(*buf)[j]);
7310 }
7311 PyMem_Del(*buf);
7312 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007313}
7314
7315static void
7316iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7317{
7318 int i;
7319 PyMem_Del(iov);
7320 for (i = 0; i < cnt; i++) {
7321 PyBuffer_Release(&buf[i]);
7322 }
7323 PyMem_Del(buf);
7324}
7325#endif
7326
Ross Lagerwall7807c352011-03-17 20:20:30 +02007327#ifdef HAVE_READV
7328PyDoc_STRVAR(posix_readv__doc__,
7329"readv(fd, buffers) -> bytesread\n\n\
7330Read from a file descriptor into a number of writable buffers. buffers\n\
7331is an arbitrary sequence of writable buffers.\n\
7332Returns the total number of bytes read.");
7333
7334static PyObject *
7335posix_readv(PyObject *self, PyObject *args)
7336{
7337 int fd, cnt;
7338 Py_ssize_t n;
7339 PyObject *seq;
7340 struct iovec *iov;
7341 Py_buffer *buf;
7342
7343 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7344 return NULL;
7345 if (!PySequence_Check(seq)) {
7346 PyErr_SetString(PyExc_TypeError,
7347 "readv() arg 2 must be a sequence");
7348 return NULL;
7349 }
7350 cnt = PySequence_Size(seq);
7351
7352 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7353 return NULL;
7354
7355 Py_BEGIN_ALLOW_THREADS
7356 n = readv(fd, iov, cnt);
7357 Py_END_ALLOW_THREADS
7358
7359 iov_cleanup(iov, buf, cnt);
7360 return PyLong_FromSsize_t(n);
7361}
7362#endif
7363
7364#ifdef HAVE_PREAD
7365PyDoc_STRVAR(posix_pread__doc__,
7366"pread(fd, buffersize, offset) -> string\n\n\
7367Read from a file descriptor, fd, at a position of offset. It will read up\n\
7368to buffersize number of bytes. The file offset remains unchanged.");
7369
7370static PyObject *
7371posix_pread(PyObject *self, PyObject *args)
7372{
7373 int fd, size;
7374 off_t offset;
7375 Py_ssize_t n;
7376 PyObject *buffer;
7377 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7378 return NULL;
7379
7380 if (size < 0) {
7381 errno = EINVAL;
7382 return posix_error();
7383 }
7384 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7385 if (buffer == NULL)
7386 return NULL;
7387 if (!_PyVerify_fd(fd)) {
7388 Py_DECREF(buffer);
7389 return posix_error();
7390 }
7391 Py_BEGIN_ALLOW_THREADS
7392 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7393 Py_END_ALLOW_THREADS
7394 if (n < 0) {
7395 Py_DECREF(buffer);
7396 return posix_error();
7397 }
7398 if (n != size)
7399 _PyBytes_Resize(&buffer, n);
7400 return buffer;
7401}
7402#endif
7403
7404PyDoc_STRVAR(posix_write__doc__,
7405"write(fd, string) -> byteswritten\n\n\
7406Write a string to a file descriptor.");
7407
7408static PyObject *
7409posix_write(PyObject *self, PyObject *args)
7410{
7411 Py_buffer pbuf;
7412 int fd;
7413 Py_ssize_t size, len;
7414
7415 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7416 return NULL;
7417 if (!_PyVerify_fd(fd)) {
7418 PyBuffer_Release(&pbuf);
7419 return posix_error();
7420 }
7421 len = pbuf.len;
7422 Py_BEGIN_ALLOW_THREADS
7423#if defined(MS_WIN64) || defined(MS_WINDOWS)
7424 if (len > INT_MAX)
7425 len = INT_MAX;
7426 size = write(fd, pbuf.buf, (int)len);
7427#else
7428 size = write(fd, pbuf.buf, len);
7429#endif
7430 Py_END_ALLOW_THREADS
7431 PyBuffer_Release(&pbuf);
7432 if (size < 0)
7433 return posix_error();
7434 return PyLong_FromSsize_t(size);
7435}
7436
7437#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007438PyDoc_STRVAR(posix_sendfile__doc__,
7439"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7440sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7441 -> byteswritten\n\
7442Copy nbytes bytes from file descriptor in to file descriptor out.");
7443
7444static PyObject *
7445posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7446{
7447 int in, out;
7448 Py_ssize_t ret;
7449 off_t offset;
7450
7451#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7452#ifndef __APPLE__
7453 Py_ssize_t len;
7454#endif
7455 PyObject *headers = NULL, *trailers = NULL;
7456 Py_buffer *hbuf, *tbuf;
7457 off_t sbytes;
7458 struct sf_hdtr sf;
7459 int flags = 0;
7460 sf.headers = NULL;
7461 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007462 static char *keywords[] = {"out", "in",
7463 "offset", "count",
7464 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007465
7466#ifdef __APPLE__
7467 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007468 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007469#else
7470 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007471 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007472#endif
7473 &headers, &trailers, &flags))
7474 return NULL;
7475 if (headers != NULL) {
7476 if (!PySequence_Check(headers)) {
7477 PyErr_SetString(PyExc_TypeError,
7478 "sendfile() headers 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.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007483 if (sf.hdr_cnt > 0 &&
7484 !(i = iov_setup(&(sf.headers), &hbuf,
7485 headers, sf.hdr_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 if (trailers != NULL) {
7493 if (!PySequence_Check(trailers)) {
7494 PyErr_SetString(PyExc_TypeError,
7495 "sendfile() trailers must be a sequence or None");
7496 return NULL;
7497 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007498 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007499 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007500 if (sf.trl_cnt > 0 &&
7501 !(i = iov_setup(&(sf.trailers), &tbuf,
7502 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007503 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007504#ifdef __APPLE__
7505 sbytes += i;
7506#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007507 }
7508 }
7509
7510 Py_BEGIN_ALLOW_THREADS
7511#ifdef __APPLE__
7512 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7513#else
7514 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7515#endif
7516 Py_END_ALLOW_THREADS
7517
7518 if (sf.headers != NULL)
7519 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7520 if (sf.trailers != NULL)
7521 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7522
7523 if (ret < 0) {
7524 if ((errno == EAGAIN) || (errno == EBUSY)) {
7525 if (sbytes != 0) {
7526 // some data has been sent
7527 goto done;
7528 }
7529 else {
7530 // no data has been sent; upper application is supposed
7531 // to retry on EAGAIN or EBUSY
7532 return posix_error();
7533 }
7534 }
7535 return posix_error();
7536 }
7537 goto done;
7538
7539done:
7540 #if !defined(HAVE_LARGEFILE_SUPPORT)
7541 return Py_BuildValue("l", sbytes);
7542 #else
7543 return Py_BuildValue("L", sbytes);
7544 #endif
7545
7546#else
7547 Py_ssize_t count;
7548 PyObject *offobj;
7549 static char *keywords[] = {"out", "in",
7550 "offset", "count", NULL};
7551 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7552 keywords, &out, &in, &offobj, &count))
7553 return NULL;
7554#ifdef linux
7555 if (offobj == Py_None) {
7556 Py_BEGIN_ALLOW_THREADS
7557 ret = sendfile(out, in, NULL, count);
7558 Py_END_ALLOW_THREADS
7559 if (ret < 0)
7560 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007561 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007562 }
7563#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007564 if (!_parse_off_t(offobj, &offset))
7565 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007566 Py_BEGIN_ALLOW_THREADS
7567 ret = sendfile(out, in, &offset, count);
7568 Py_END_ALLOW_THREADS
7569 if (ret < 0)
7570 return posix_error();
7571 return Py_BuildValue("n", ret);
7572#endif
7573}
7574#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007575
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007576PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007577"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007578Like stat(), but for an open file descriptor.\n\
7579Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007580
Barry Warsaw53699e91996-12-10 23:23:01 +00007581static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007582posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007583{
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 int fd;
7585 STRUCT_STAT st;
7586 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007587 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007588 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007589#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007590 /* on OpenVMS we must ensure that all bytes are written to the file */
7591 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007592#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007593 Py_BEGIN_ALLOW_THREADS
7594 res = FSTAT(fd, &st);
7595 Py_END_ALLOW_THREADS
7596 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007597#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01007598 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00007599#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007601#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007602 }
Tim Peters5aa91602002-01-30 05:46:57 +00007603
Victor Stinner4195b5c2012-02-08 23:03:19 +01007604 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007605}
7606
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007607PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007608"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007609Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007610connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007611
7612static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007613posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007614{
Victor Stinner8c62be82010-05-06 00:08:46 +00007615 int fd;
7616 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7617 return NULL;
7618 if (!_PyVerify_fd(fd))
7619 return PyBool_FromLong(0);
7620 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007621}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007622
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007623#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007624PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007625"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007626Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007627
Barry Warsaw53699e91996-12-10 23:23:01 +00007628static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007629posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007630{
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007631#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007632 int fds[2];
7633 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007634 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007635 if (res != 0)
7636 return posix_error();
7637 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007638#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 HANDLE read, write;
7640 int read_fd, write_fd;
7641 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01007644 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007645 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7646 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7647 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007648#endif /* MS_WINDOWS */
Guido van Rossum687dd131993-05-17 08:34:16 +00007649}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007650#endif /* HAVE_PIPE */
7651
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007652#ifdef HAVE_PIPE2
7653PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007654"pipe2(flags) -> (read_end, write_end)\n\n\
7655Create a pipe with flags set atomically.\n\
7656flags can be constructed by ORing together one or more of these values:\n\
7657O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007658");
7659
7660static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007661posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007662{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007663 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007664 int fds[2];
7665 int res;
7666
Charles-François Natali368f34b2011-06-06 19:49:47 +02007667 flags = PyLong_AsLong(arg);
7668 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007669 return NULL;
7670
7671 res = pipe2(fds, flags);
7672 if (res != 0)
7673 return posix_error();
7674 return Py_BuildValue("(ii)", fds[0], fds[1]);
7675}
7676#endif /* HAVE_PIPE2 */
7677
Ross Lagerwall7807c352011-03-17 20:20:30 +02007678#ifdef HAVE_WRITEV
7679PyDoc_STRVAR(posix_writev__doc__,
7680"writev(fd, buffers) -> byteswritten\n\n\
7681Write the contents of buffers to a file descriptor, where buffers is an\n\
7682arbitrary sequence of buffers.\n\
7683Returns the total bytes written.");
7684
7685static PyObject *
7686posix_writev(PyObject *self, PyObject *args)
7687{
7688 int fd, cnt;
7689 Py_ssize_t res;
7690 PyObject *seq;
7691 struct iovec *iov;
7692 Py_buffer *buf;
7693 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7694 return NULL;
7695 if (!PySequence_Check(seq)) {
7696 PyErr_SetString(PyExc_TypeError,
7697 "writev() arg 2 must be a sequence");
7698 return NULL;
7699 }
7700 cnt = PySequence_Size(seq);
7701
7702 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7703 return NULL;
7704 }
7705
7706 Py_BEGIN_ALLOW_THREADS
7707 res = writev(fd, iov, cnt);
7708 Py_END_ALLOW_THREADS
7709
7710 iov_cleanup(iov, buf, cnt);
7711 return PyLong_FromSsize_t(res);
7712}
7713#endif
7714
7715#ifdef HAVE_PWRITE
7716PyDoc_STRVAR(posix_pwrite__doc__,
7717"pwrite(fd, string, offset) -> byteswritten\n\n\
7718Write string to a file descriptor, fd, from offset, leaving the file\n\
7719offset unchanged.");
7720
7721static PyObject *
7722posix_pwrite(PyObject *self, PyObject *args)
7723{
7724 Py_buffer pbuf;
7725 int fd;
7726 off_t offset;
7727 Py_ssize_t size;
7728
7729 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7730 return NULL;
7731
7732 if (!_PyVerify_fd(fd)) {
7733 PyBuffer_Release(&pbuf);
7734 return posix_error();
7735 }
7736 Py_BEGIN_ALLOW_THREADS
7737 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7738 Py_END_ALLOW_THREADS
7739 PyBuffer_Release(&pbuf);
7740 if (size < 0)
7741 return posix_error();
7742 return PyLong_FromSsize_t(size);
7743}
7744#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007745
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007746#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007747PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007748"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
7749Create a FIFO (a POSIX named pipe).\n\
7750\n\
7751If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7752 and path should be relative; path will then be relative to that directory.\n\
7753dir_fd may not be implemented on your platform.\n\
7754 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007755
Barry Warsaw53699e91996-12-10 23:23:01 +00007756static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007757posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007758{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007759 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007761 int dir_fd = DEFAULT_DIR_FD;
7762 int result;
7763 PyObject *return_value = NULL;
7764 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
7765
7766 memset(&path, 0, sizeof(path));
7767 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
7768 path_converter, &path,
7769 &mode,
7770#ifdef HAVE_MKFIFOAT
7771 dir_fd_converter, &dir_fd
7772#else
7773 dir_fd_unavailable, &dir_fd
7774#endif
7775 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007776 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007777
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007779#ifdef HAVE_MKFIFOAT
7780 if (dir_fd != DEFAULT_DIR_FD)
7781 result = mkfifoat(dir_fd, path.narrow, mode);
7782 else
7783#endif
7784 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007786
7787 if (result < 0) {
7788 return_value = posix_error();
7789 goto exit;
7790 }
7791
7792 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007794
7795exit:
7796 path_cleanup(&path);
7797 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007798}
7799#endif
7800
Neal Norwitz11690112002-07-30 01:08:28 +00007801#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007802PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007803"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007804Create a filesystem node (file, device special file or named pipe)\n\
7805named filename. mode specifies both the permissions to use and the\n\
7806type of node to be created, being combined (bitwise OR) with one of\n\
7807S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007808device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007809os.makedev()), otherwise it is ignored.\n\
7810\n\
7811If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7812 and path should be relative; path will then be relative to that directory.\n\
7813dir_fd may not be implemented on your platform.\n\
7814 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007815
7816
7817static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007818posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007819{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007820 path_t path;
7821 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007823 int dir_fd = DEFAULT_DIR_FD;
7824 int result;
7825 PyObject *return_value = NULL;
7826 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
7827
7828 memset(&path, 0, sizeof(path));
7829 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
7830 path_converter, &path,
7831 &mode, &device,
7832#ifdef HAVE_MKNODAT
7833 dir_fd_converter, &dir_fd
7834#else
7835 dir_fd_unavailable, &dir_fd
7836#endif
7837 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007839
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007841#ifdef HAVE_MKNODAT
7842 if (dir_fd != DEFAULT_DIR_FD)
7843 result = mknodat(dir_fd, path.narrow, mode, device);
7844 else
7845#endif
7846 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007848
7849 if (result < 0) {
7850 return_value = posix_error();
7851 goto exit;
7852 }
7853
7854 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02007856
Larry Hastings9cf065c2012-06-22 16:30:09 -07007857exit:
7858 path_cleanup(&path);
7859 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007860}
7861#endif
7862
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007863#ifdef HAVE_DEVICE_MACROS
7864PyDoc_STRVAR(posix_major__doc__,
7865"major(device) -> major number\n\
7866Extracts a device major number from a raw device number.");
7867
7868static PyObject *
7869posix_major(PyObject *self, PyObject *args)
7870{
Victor Stinner8c62be82010-05-06 00:08:46 +00007871 int device;
7872 if (!PyArg_ParseTuple(args, "i:major", &device))
7873 return NULL;
7874 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007875}
7876
7877PyDoc_STRVAR(posix_minor__doc__,
7878"minor(device) -> minor number\n\
7879Extracts a device minor number from a raw device number.");
7880
7881static PyObject *
7882posix_minor(PyObject *self, PyObject *args)
7883{
Victor Stinner8c62be82010-05-06 00:08:46 +00007884 int device;
7885 if (!PyArg_ParseTuple(args, "i:minor", &device))
7886 return NULL;
7887 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007888}
7889
7890PyDoc_STRVAR(posix_makedev__doc__,
7891"makedev(major, minor) -> device number\n\
7892Composes a raw device number from the major and minor device numbers.");
7893
7894static PyObject *
7895posix_makedev(PyObject *self, PyObject *args)
7896{
Victor Stinner8c62be82010-05-06 00:08:46 +00007897 int major, minor;
7898 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7899 return NULL;
7900 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007901}
7902#endif /* device macros */
7903
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007904
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007905#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007906PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007907"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007908Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007909
Barry Warsaw53699e91996-12-10 23:23:01 +00007910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007911posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007912{
Victor Stinner8c62be82010-05-06 00:08:46 +00007913 int fd;
7914 off_t length;
7915 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007916
Ross Lagerwall7807c352011-03-17 20:20:30 +02007917 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007919
Victor Stinner8c62be82010-05-06 00:08:46 +00007920 Py_BEGIN_ALLOW_THREADS
7921 res = ftruncate(fd, length);
7922 Py_END_ALLOW_THREADS
7923 if (res < 0)
7924 return posix_error();
7925 Py_INCREF(Py_None);
7926 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007927}
7928#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007929
Ross Lagerwall7807c352011-03-17 20:20:30 +02007930#ifdef HAVE_TRUNCATE
7931PyDoc_STRVAR(posix_truncate__doc__,
7932"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02007933Truncate the file given by path to length bytes.\n\
7934On some platforms, path may also be specified as an open file descriptor.\n\
7935 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02007936
7937static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02007938posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02007939{
Georg Brandl306336b2012-06-24 12:55:33 +02007940 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007941 off_t length;
7942 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02007943 PyObject *result = NULL;
7944 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02007945
Georg Brandl306336b2012-06-24 12:55:33 +02007946 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007947 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02007948#ifdef HAVE_FTRUNCATE
7949 path.allow_fd = 1;
7950#endif
7951 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
7952 path_converter, &path,
7953 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02007954 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007955
7956 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02007957#ifdef HAVE_FTRUNCATE
7958 if (path.fd != -1)
7959 res = ftruncate(path.fd, length);
7960 else
7961#endif
7962 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007963 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02007964 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01007965 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02007966 else {
7967 Py_INCREF(Py_None);
7968 result = Py_None;
7969 }
7970 path_cleanup(&path);
7971 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007972}
7973#endif
7974
7975#ifdef HAVE_POSIX_FALLOCATE
7976PyDoc_STRVAR(posix_posix_fallocate__doc__,
7977"posix_fallocate(fd, offset, len)\n\n\
7978Ensures that enough disk space is allocated for the file specified by fd\n\
7979starting from offset and continuing for len bytes.");
7980
7981static PyObject *
7982posix_posix_fallocate(PyObject *self, PyObject *args)
7983{
7984 off_t len, offset;
7985 int res, fd;
7986
7987 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7988 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7989 return NULL;
7990
7991 Py_BEGIN_ALLOW_THREADS
7992 res = posix_fallocate(fd, offset, len);
7993 Py_END_ALLOW_THREADS
7994 if (res != 0) {
7995 errno = res;
7996 return posix_error();
7997 }
7998 Py_RETURN_NONE;
7999}
8000#endif
8001
8002#ifdef HAVE_POSIX_FADVISE
8003PyDoc_STRVAR(posix_posix_fadvise__doc__,
8004"posix_fadvise(fd, offset, len, advice)\n\n\
8005Announces an intention to access data in a specific pattern thus allowing\n\
8006the kernel to make optimizations.\n\
8007The advice applies to the region of the file specified by fd starting at\n\
8008offset and continuing for len bytes.\n\
8009advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8010POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8011POSIX_FADV_DONTNEED.");
8012
8013static PyObject *
8014posix_posix_fadvise(PyObject *self, PyObject *args)
8015{
8016 off_t len, offset;
8017 int res, fd, advice;
8018
8019 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8020 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8021 return NULL;
8022
8023 Py_BEGIN_ALLOW_THREADS
8024 res = posix_fadvise(fd, offset, len, advice);
8025 Py_END_ALLOW_THREADS
8026 if (res != 0) {
8027 errno = res;
8028 return posix_error();
8029 }
8030 Py_RETURN_NONE;
8031}
8032#endif
8033
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008034#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008035PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008036"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008037Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008038
Fred Drake762e2061999-08-26 17:23:54 +00008039/* Save putenv() parameters as values here, so we can collect them when they
8040 * get re-set with another call for the same key. */
8041static PyObject *posix_putenv_garbage;
8042
Tim Peters5aa91602002-01-30 05:46:57 +00008043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008044posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008045{
Victor Stinner84ae1182010-05-06 22:05:07 +00008046 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008047#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008048 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008049 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008050
Victor Stinner8c62be82010-05-06 00:08:46 +00008051 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008052 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008053 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008054 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008055
Victor Stinner65170952011-11-22 22:16:17 +01008056 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008057 if (newstr == NULL) {
8058 PyErr_NoMemory();
8059 goto error;
8060 }
Victor Stinner65170952011-11-22 22:16:17 +01008061 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8062 PyErr_Format(PyExc_ValueError,
8063 "the environment variable is longer than %u characters",
8064 _MAX_ENV);
8065 goto error;
8066 }
8067
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008069 if (newenv == NULL)
8070 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008071 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008072 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008073 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008074 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008075#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008076 PyObject *os1, *os2;
8077 char *s1, *s2;
8078 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008079
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008080 if (!PyArg_ParseTuple(args,
8081 "O&O&:putenv",
8082 PyUnicode_FSConverter, &os1,
8083 PyUnicode_FSConverter, &os2))
8084 return NULL;
8085 s1 = PyBytes_AsString(os1);
8086 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008087
Victor Stinner65170952011-11-22 22:16:17 +01008088 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008089 if (newstr == NULL) {
8090 PyErr_NoMemory();
8091 goto error;
8092 }
8093
Victor Stinner8c62be82010-05-06 00:08:46 +00008094 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008095 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008096 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008097 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008098 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008099#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008100
Victor Stinner8c62be82010-05-06 00:08:46 +00008101 /* Install the first arg and newstr in posix_putenv_garbage;
8102 * this will cause previous value to be collected. This has to
8103 * happen after the real putenv() call because the old value
8104 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008105 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 /* really not much we can do; just leak */
8107 PyErr_Clear();
8108 }
8109 else {
8110 Py_DECREF(newstr);
8111 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008112
Martin v. Löwis011e8422009-05-05 04:43:17 +00008113#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008114 Py_DECREF(os1);
8115 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008116#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008117 Py_RETURN_NONE;
8118
8119error:
8120#ifndef MS_WINDOWS
8121 Py_DECREF(os1);
8122 Py_DECREF(os2);
8123#endif
8124 Py_XDECREF(newstr);
8125 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008126}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008127#endif /* putenv */
8128
Guido van Rossumc524d952001-10-19 01:31:59 +00008129#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008130PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008131"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008132Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008133
8134static PyObject *
8135posix_unsetenv(PyObject *self, PyObject *args)
8136{
Victor Stinner65170952011-11-22 22:16:17 +01008137 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008138#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008139 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008140#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008141
8142 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008143
Victor Stinner65170952011-11-22 22:16:17 +01008144 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008145 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008146
Victor Stinner984890f2011-11-24 13:53:38 +01008147#ifdef HAVE_BROKEN_UNSETENV
8148 unsetenv(PyBytes_AS_STRING(name));
8149#else
Victor Stinner65170952011-11-22 22:16:17 +01008150 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008151 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008152 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008153 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008154 }
Victor Stinner984890f2011-11-24 13:53:38 +01008155#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008156
Victor Stinner8c62be82010-05-06 00:08:46 +00008157 /* Remove the key from posix_putenv_garbage;
8158 * this will cause it to be collected. This has to
8159 * happen after the real unsetenv() call because the
8160 * old value was still accessible until then.
8161 */
Victor Stinner65170952011-11-22 22:16:17 +01008162 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 /* really not much we can do; just leak */
8164 PyErr_Clear();
8165 }
Victor Stinner65170952011-11-22 22:16:17 +01008166 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008167 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008168}
8169#endif /* unsetenv */
8170
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008171PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008172"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008173Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008174
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008176posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008177{
Victor Stinner8c62be82010-05-06 00:08:46 +00008178 int code;
8179 char *message;
8180 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8181 return NULL;
8182 message = strerror(code);
8183 if (message == NULL) {
8184 PyErr_SetString(PyExc_ValueError,
8185 "strerror() argument out of range");
8186 return NULL;
8187 }
Victor Stinner1b579672011-12-17 05:47:23 +01008188 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008189}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008190
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008191
Guido van Rossumc9641791998-08-04 15:26:23 +00008192#ifdef HAVE_SYS_WAIT_H
8193
Fred Drake106c1a02002-04-23 15:58:02 +00008194#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008195PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008196"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008197Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008198
8199static PyObject *
8200posix_WCOREDUMP(PyObject *self, PyObject *args)
8201{
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 WAIT_TYPE status;
8203 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008204
Victor Stinner8c62be82010-05-06 00:08:46 +00008205 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8206 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008207
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008209}
8210#endif /* WCOREDUMP */
8211
8212#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008213PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008214"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008215Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008216job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008217
8218static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008219posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008220{
Victor Stinner8c62be82010-05-06 00:08:46 +00008221 WAIT_TYPE status;
8222 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008223
Victor Stinner8c62be82010-05-06 00:08:46 +00008224 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8225 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008226
Victor Stinner8c62be82010-05-06 00:08:46 +00008227 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008228}
8229#endif /* WIFCONTINUED */
8230
Guido van Rossumc9641791998-08-04 15:26:23 +00008231#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008232PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008233"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008234Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008235
8236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008237posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008238{
Victor Stinner8c62be82010-05-06 00:08:46 +00008239 WAIT_TYPE status;
8240 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008241
Victor Stinner8c62be82010-05-06 00:08:46 +00008242 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8243 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008244
Victor Stinner8c62be82010-05-06 00:08:46 +00008245 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008246}
8247#endif /* WIFSTOPPED */
8248
8249#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008250PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008251"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008252Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008253
8254static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008255posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008256{
Victor Stinner8c62be82010-05-06 00:08:46 +00008257 WAIT_TYPE status;
8258 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008259
Victor Stinner8c62be82010-05-06 00:08:46 +00008260 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8261 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008262
Victor Stinner8c62be82010-05-06 00:08:46 +00008263 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008264}
8265#endif /* WIFSIGNALED */
8266
8267#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008268PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008269"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008270Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008271system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008272
8273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008274posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008275{
Victor Stinner8c62be82010-05-06 00:08:46 +00008276 WAIT_TYPE status;
8277 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008278
Victor Stinner8c62be82010-05-06 00:08:46 +00008279 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8280 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008281
Victor Stinner8c62be82010-05-06 00:08:46 +00008282 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008283}
8284#endif /* WIFEXITED */
8285
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008286#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008287PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008288"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008289Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008290
8291static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008292posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008293{
Victor Stinner8c62be82010-05-06 00:08:46 +00008294 WAIT_TYPE status;
8295 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008296
Victor Stinner8c62be82010-05-06 00:08:46 +00008297 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8298 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008299
Victor Stinner8c62be82010-05-06 00:08:46 +00008300 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008301}
8302#endif /* WEXITSTATUS */
8303
8304#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008305PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008306"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008307Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008308value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008309
8310static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008311posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008312{
Victor Stinner8c62be82010-05-06 00:08:46 +00008313 WAIT_TYPE status;
8314 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008315
Victor Stinner8c62be82010-05-06 00:08:46 +00008316 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8317 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008318
Victor Stinner8c62be82010-05-06 00:08:46 +00008319 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008320}
8321#endif /* WTERMSIG */
8322
8323#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008324PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008325"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008326Return the signal that stopped the process that provided\n\
8327the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008328
8329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008330posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008331{
Victor Stinner8c62be82010-05-06 00:08:46 +00008332 WAIT_TYPE status;
8333 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008334
Victor Stinner8c62be82010-05-06 00:08:46 +00008335 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8336 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008337
Victor Stinner8c62be82010-05-06 00:08:46 +00008338 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008339}
8340#endif /* WSTOPSIG */
8341
8342#endif /* HAVE_SYS_WAIT_H */
8343
8344
Thomas Wouters477c8d52006-05-27 19:21:47 +00008345#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008346#ifdef _SCO_DS
8347/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8348 needed definitions in sys/statvfs.h */
8349#define _SVID3
8350#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008351#include <sys/statvfs.h>
8352
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008353static PyObject*
8354_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008355 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8356 if (v == NULL)
8357 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008358
8359#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008360 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8361 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8362 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8363 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8364 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8365 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8366 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8367 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((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#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008371 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8372 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8373 PyStructSequence_SET_ITEM(v, 2,
8374 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8375 PyStructSequence_SET_ITEM(v, 3,
8376 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8377 PyStructSequence_SET_ITEM(v, 4,
8378 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8379 PyStructSequence_SET_ITEM(v, 5,
8380 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8381 PyStructSequence_SET_ITEM(v, 6,
8382 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8383 PyStructSequence_SET_ITEM(v, 7,
8384 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8385 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8386 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008387#endif
8388
Victor Stinner8c62be82010-05-06 00:08:46 +00008389 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008390}
8391
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008392PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008393"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008394Perform an fstatvfs system call on the given fd.\n\
8395Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008396
8397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008398posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008399{
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 int fd, res;
8401 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008402
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8404 return NULL;
8405 Py_BEGIN_ALLOW_THREADS
8406 res = fstatvfs(fd, &st);
8407 Py_END_ALLOW_THREADS
8408 if (res != 0)
8409 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008410
Victor Stinner8c62be82010-05-06 00:08:46 +00008411 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008412}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008413#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008414
8415
Thomas Wouters477c8d52006-05-27 19:21:47 +00008416#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008417#include <sys/statvfs.h>
8418
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008419PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008420"statvfs(path)\n\n\
8421Perform a statvfs system call on the given path.\n\
8422\n\
8423path may always be specified as a string.\n\
8424On some platforms, path may also be specified as an open file descriptor.\n\
8425 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008426
8427static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008428posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008429{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008430 static char *keywords[] = {"path", NULL};
8431 path_t path;
8432 int result;
8433 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008435
Larry Hastings9cf065c2012-06-22 16:30:09 -07008436 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008437 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07008438#ifdef HAVE_FSTATVFS
8439 path.allow_fd = 1;
8440#endif
8441 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8442 path_converter, &path
8443 ))
8444 return NULL;
8445
8446 Py_BEGIN_ALLOW_THREADS
8447#ifdef HAVE_FSTATVFS
8448 if (path.fd != -1) {
8449#ifdef __APPLE__
8450 /* handle weak-linking on Mac OS X 10.3 */
8451 if (fstatvfs == NULL) {
8452 fd_specified("statvfs", path.fd);
8453 goto exit;
8454 }
8455#endif
8456 result = fstatvfs(path.fd, &st);
8457 }
8458 else
8459#endif
8460 result = statvfs(path.narrow, &st);
8461 Py_END_ALLOW_THREADS
8462
8463 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01008464 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008465 goto exit;
8466 }
8467
8468 return_value = _pystatvfs_fromstructstatvfs(st);
8469
8470exit:
8471 path_cleanup(&path);
8472 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008473}
8474#endif /* HAVE_STATVFS */
8475
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008476#ifdef MS_WINDOWS
8477PyDoc_STRVAR(win32__getdiskusage__doc__,
8478"_getdiskusage(path) -> (total, free)\n\n\
8479Return disk usage statistics about the given path as (total, free) tuple.");
8480
8481static PyObject *
8482win32__getdiskusage(PyObject *self, PyObject *args)
8483{
8484 BOOL retval;
8485 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008486 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008487
Victor Stinner6139c1b2011-11-09 22:14:14 +01008488 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008489 return NULL;
8490
8491 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008492 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008493 Py_END_ALLOW_THREADS
8494 if (retval == 0)
8495 return PyErr_SetFromWindowsErr(0);
8496
8497 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8498}
8499#endif
8500
8501
Fred Drakec9680921999-12-13 16:37:25 +00008502/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8503 * It maps strings representing configuration variable names to
8504 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008505 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008506 * rarely-used constants. There are three separate tables that use
8507 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008508 *
8509 * This code is always included, even if none of the interfaces that
8510 * need it are included. The #if hackery needed to avoid it would be
8511 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008512 */
8513struct constdef {
8514 char *name;
8515 long value;
8516};
8517
Fred Drake12c6e2d1999-12-14 21:25:03 +00008518static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008519conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008520 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008521{
Christian Heimes217cfd12007-12-02 14:31:20 +00008522 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008523 *valuep = PyLong_AS_LONG(arg);
8524 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008525 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008526 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008527 /* look up the value in the table using a binary search */
8528 size_t lo = 0;
8529 size_t mid;
8530 size_t hi = tablesize;
8531 int cmp;
8532 const char *confname;
8533 if (!PyUnicode_Check(arg)) {
8534 PyErr_SetString(PyExc_TypeError,
8535 "configuration names must be strings or integers");
8536 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008537 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008538 confname = _PyUnicode_AsString(arg);
8539 if (confname == NULL)
8540 return 0;
8541 while (lo < hi) {
8542 mid = (lo + hi) / 2;
8543 cmp = strcmp(confname, table[mid].name);
8544 if (cmp < 0)
8545 hi = mid;
8546 else if (cmp > 0)
8547 lo = mid + 1;
8548 else {
8549 *valuep = table[mid].value;
8550 return 1;
8551 }
8552 }
8553 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8554 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008555 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008556}
8557
8558
8559#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8560static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008561#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008562 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008563#endif
8564#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008565 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008566#endif
Fred Drakec9680921999-12-13 16:37:25 +00008567#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008568 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008569#endif
8570#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008571 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008572#endif
8573#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008574 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008575#endif
8576#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008577 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008578#endif
8579#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008581#endif
8582#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008583 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008584#endif
8585#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008586 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008587#endif
8588#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008589 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008590#endif
8591#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008592 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008593#endif
8594#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008595 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008596#endif
8597#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008598 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008599#endif
8600#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008601 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008602#endif
8603#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008604 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008605#endif
8606#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008607 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008608#endif
8609#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008610 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008611#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008612#ifdef _PC_ACL_ENABLED
8613 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8614#endif
8615#ifdef _PC_MIN_HOLE_SIZE
8616 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8617#endif
8618#ifdef _PC_ALLOC_SIZE_MIN
8619 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8620#endif
8621#ifdef _PC_REC_INCR_XFER_SIZE
8622 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8623#endif
8624#ifdef _PC_REC_MAX_XFER_SIZE
8625 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8626#endif
8627#ifdef _PC_REC_MIN_XFER_SIZE
8628 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8629#endif
8630#ifdef _PC_REC_XFER_ALIGN
8631 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8632#endif
8633#ifdef _PC_SYMLINK_MAX
8634 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8635#endif
8636#ifdef _PC_XATTR_ENABLED
8637 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8638#endif
8639#ifdef _PC_XATTR_EXISTS
8640 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8641#endif
8642#ifdef _PC_TIMESTAMP_RESOLUTION
8643 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8644#endif
Fred Drakec9680921999-12-13 16:37:25 +00008645};
8646
Fred Drakec9680921999-12-13 16:37:25 +00008647static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008648conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008649{
8650 return conv_confname(arg, valuep, posix_constants_pathconf,
8651 sizeof(posix_constants_pathconf)
8652 / sizeof(struct constdef));
8653}
8654#endif
8655
8656#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008657PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008658"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008659Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008660If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008661
8662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008663posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008664{
8665 PyObject *result = NULL;
8666 int name, fd;
8667
Fred Drake12c6e2d1999-12-14 21:25:03 +00008668 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8669 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008670 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008671
Stefan Krah0e803b32010-11-26 16:16:47 +00008672 errno = 0;
8673 limit = fpathconf(fd, name);
8674 if (limit == -1 && errno != 0)
8675 posix_error();
8676 else
8677 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008678 }
8679 return result;
8680}
8681#endif
8682
8683
8684#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008685PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008686"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008687Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008688If there is no limit, return -1.\n\
8689On some platforms, path may also be specified as an open file descriptor.\n\
8690 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00008691
8692static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008693posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00008694{
Georg Brandl306336b2012-06-24 12:55:33 +02008695 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00008696 PyObject *result = NULL;
8697 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02008698 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00008699
Georg Brandl306336b2012-06-24 12:55:33 +02008700 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008701 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02008702#ifdef HAVE_FPATHCONF
8703 path.allow_fd = 1;
8704#endif
8705 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
8706 path_converter, &path,
8707 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008708 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008709
Victor Stinner8c62be82010-05-06 00:08:46 +00008710 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02008711#ifdef HAVE_FPATHCONF
8712 if (path.fd != -1)
8713 limit = fpathconf(path.fd, name);
8714 else
8715#endif
8716 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00008717 if (limit == -1 && errno != 0) {
8718 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008719 /* could be a path or name problem */
8720 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008721 else
Victor Stinner292c8352012-10-30 02:17:38 +01008722 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008723 }
8724 else
8725 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008726 }
Georg Brandl306336b2012-06-24 12:55:33 +02008727 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00008728 return result;
8729}
8730#endif
8731
8732#ifdef HAVE_CONFSTR
8733static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008734#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008735 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008736#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008737#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008738 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008739#endif
8740#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008741 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008742#endif
Fred Draked86ed291999-12-15 15:34:33 +00008743#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008744 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008745#endif
8746#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008747 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008748#endif
8749#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008750 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008751#endif
8752#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008753 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008754#endif
Fred Drakec9680921999-12-13 16:37:25 +00008755#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008756 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008757#endif
8758#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008759 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008760#endif
8761#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008762 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008763#endif
8764#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008765 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008766#endif
8767#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008768 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008769#endif
8770#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008771 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008772#endif
8773#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008774 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008775#endif
8776#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008777 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008778#endif
Fred Draked86ed291999-12-15 15:34:33 +00008779#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008780 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008781#endif
Fred Drakec9680921999-12-13 16:37:25 +00008782#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008783 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008784#endif
Fred Draked86ed291999-12-15 15:34:33 +00008785#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008786 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008787#endif
8788#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008789 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008790#endif
8791#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008792 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008793#endif
8794#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008795 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008796#endif
Fred Drakec9680921999-12-13 16:37:25 +00008797#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008798 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008799#endif
8800#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008801 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008802#endif
8803#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008804 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008805#endif
8806#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008807 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008808#endif
8809#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008810 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008811#endif
8812#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008813 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008814#endif
8815#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008816 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008817#endif
8818#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008819 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008820#endif
8821#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008822 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008823#endif
8824#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008825 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008826#endif
8827#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008828 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008829#endif
8830#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008831 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008832#endif
8833#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008834 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008835#endif
8836#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008838#endif
8839#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008841#endif
8842#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008844#endif
Fred Draked86ed291999-12-15 15:34:33 +00008845#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008846 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008847#endif
8848#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008849 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008850#endif
8851#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008853#endif
8854#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008856#endif
8857#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008859#endif
8860#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008862#endif
8863#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008865#endif
8866#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008867 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008868#endif
8869#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008870 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008871#endif
8872#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008874#endif
8875#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008876 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008877#endif
8878#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008879 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008880#endif
8881#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008882 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008883#endif
Fred Drakec9680921999-12-13 16:37:25 +00008884};
8885
8886static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008887conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008888{
8889 return conv_confname(arg, valuep, posix_constants_confstr,
8890 sizeof(posix_constants_confstr)
8891 / sizeof(struct constdef));
8892}
8893
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008894PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008895"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008896Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008897
8898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008899posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008900{
8901 PyObject *result = NULL;
8902 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008903 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008904 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008905
Victor Stinnercb043522010-09-10 23:49:04 +00008906 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8907 return NULL;
8908
8909 errno = 0;
8910 len = confstr(name, buffer, sizeof(buffer));
8911 if (len == 0) {
8912 if (errno) {
8913 posix_error();
8914 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008915 }
8916 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008917 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008918 }
8919 }
Victor Stinnercb043522010-09-10 23:49:04 +00008920
8921 if ((unsigned int)len >= sizeof(buffer)) {
8922 char *buf = PyMem_Malloc(len);
8923 if (buf == NULL)
8924 return PyErr_NoMemory();
8925 confstr(name, buf, len);
8926 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8927 PyMem_Free(buf);
8928 }
8929 else
8930 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008931 return result;
8932}
8933#endif
8934
8935
8936#ifdef HAVE_SYSCONF
8937static struct constdef posix_constants_sysconf[] = {
8938#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008940#endif
8941#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008943#endif
8944#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008946#endif
8947#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008949#endif
8950#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008952#endif
8953#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008954 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008955#endif
8956#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008957 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008958#endif
8959#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008960 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008961#endif
8962#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008963 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008964#endif
8965#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008966 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008967#endif
Fred Draked86ed291999-12-15 15:34:33 +00008968#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008969 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008970#endif
8971#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008972 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008973#endif
Fred Drakec9680921999-12-13 16:37:25 +00008974#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008975 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008976#endif
Fred Drakec9680921999-12-13 16:37:25 +00008977#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008978 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008979#endif
8980#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008981 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008982#endif
8983#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008984 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008985#endif
8986#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008987 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008988#endif
8989#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008990 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008991#endif
Fred Draked86ed291999-12-15 15:34:33 +00008992#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008993 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008994#endif
Fred Drakec9680921999-12-13 16:37:25 +00008995#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008996 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008997#endif
8998#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008999 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009000#endif
9001#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009002 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009003#endif
9004#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009005 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009006#endif
9007#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009008 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009009#endif
Fred Draked86ed291999-12-15 15:34:33 +00009010#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009011 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009012#endif
Fred Drakec9680921999-12-13 16:37:25 +00009013#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009014 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009015#endif
9016#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009017 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009018#endif
9019#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009020 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009021#endif
9022#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009023 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009024#endif
9025#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009026 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009027#endif
9028#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009029 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009030#endif
9031#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009032 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009033#endif
9034#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009035 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009036#endif
9037#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009038 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009039#endif
9040#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009041 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009042#endif
9043#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009044 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009045#endif
9046#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009047 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009048#endif
9049#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009050 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009051#endif
9052#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009054#endif
9055#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009056 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009057#endif
9058#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009059 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009060#endif
9061#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009063#endif
9064#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009065 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009066#endif
9067#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009069#endif
9070#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009072#endif
9073#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009074 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009075#endif
9076#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009078#endif
9079#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009081#endif
Fred Draked86ed291999-12-15 15:34:33 +00009082#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009084#endif
Fred Drakec9680921999-12-13 16:37:25 +00009085#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009087#endif
9088#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009090#endif
9091#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009092 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009093#endif
Fred Draked86ed291999-12-15 15:34:33 +00009094#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009096#endif
Fred Drakec9680921999-12-13 16:37:25 +00009097#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009098 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009099#endif
Fred Draked86ed291999-12-15 15:34:33 +00009100#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009102#endif
9103#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009105#endif
Fred Drakec9680921999-12-13 16:37:25 +00009106#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009108#endif
9109#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009111#endif
9112#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009114#endif
9115#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009117#endif
Fred Draked86ed291999-12-15 15:34:33 +00009118#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009119 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009120#endif
Fred Drakec9680921999-12-13 16:37:25 +00009121#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009123#endif
9124#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009125 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009126#endif
9127#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009128 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009129#endif
9130#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009131 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009132#endif
9133#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009134 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009135#endif
9136#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009137 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009138#endif
9139#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009140 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009141#endif
Fred Draked86ed291999-12-15 15:34:33 +00009142#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009144#endif
Fred Drakec9680921999-12-13 16:37:25 +00009145#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009147#endif
9148#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009149 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009150#endif
Fred Draked86ed291999-12-15 15:34:33 +00009151#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009152 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009153#endif
Fred Drakec9680921999-12-13 16:37:25 +00009154#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009155 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009156#endif
9157#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009159#endif
9160#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009162#endif
9163#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009165#endif
9166#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009168#endif
9169#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009170 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009171#endif
9172#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009173 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009174#endif
9175#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009176 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009177#endif
9178#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009179 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009180#endif
Fred Draked86ed291999-12-15 15:34:33 +00009181#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009182 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009183#endif
9184#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009185 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009186#endif
Fred Drakec9680921999-12-13 16:37:25 +00009187#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009188 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009189#endif
9190#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009191 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009192#endif
9193#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009195#endif
9196#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009197 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009198#endif
9199#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009200 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009201#endif
9202#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009203 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009204#endif
9205#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009206 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009207#endif
9208#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009210#endif
9211#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009212 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009213#endif
9214#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009215 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009216#endif
9217#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009218 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009219#endif
9220#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009221 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009222#endif
9223#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009225#endif
9226#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009227 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009228#endif
9229#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009230 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009231#endif
9232#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009233 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009234#endif
9235#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009236 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009237#endif
9238#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009239 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009240#endif
9241#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009242 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009243#endif
9244#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009246#endif
9247#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009248 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009249#endif
9250#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009252#endif
9253#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009254 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009255#endif
9256#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009258#endif
9259#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009260 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009261#endif
9262#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009263 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009264#endif
9265#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009266 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009267#endif
9268#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009269 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009270#endif
9271#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009272 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009273#endif
9274#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009275 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009276#endif
9277#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009279#endif
9280#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009281 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009282#endif
9283#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009284 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009285#endif
9286#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009287 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009288#endif
9289#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009290 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009291#endif
Fred Draked86ed291999-12-15 15:34:33 +00009292#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009293 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009294#endif
Fred Drakec9680921999-12-13 16:37:25 +00009295#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009296 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009297#endif
9298#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009299 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009300#endif
9301#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009302 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009303#endif
9304#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009306#endif
9307#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009309#endif
9310#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009312#endif
9313#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009315#endif
9316#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009318#endif
9319#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009321#endif
9322#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009324#endif
9325#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009327#endif
9328#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009330#endif
9331#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009333#endif
9334#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009336#endif
9337#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009339#endif
9340#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009342#endif
9343#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009345#endif
9346#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009348#endif
9349#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009351#endif
9352#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009354#endif
9355#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009357#endif
9358#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009360#endif
9361#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
9370#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009372#endif
9373#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009375#endif
9376#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009378#endif
9379#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009381#endif
9382#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009384#endif
9385#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009387#endif
9388#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009390#endif
9391#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009393#endif
9394#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009396#endif
9397#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009399#endif
9400#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009402#endif
9403#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009404 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009405#endif
9406#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009407 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009408#endif
9409#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009410 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009411#endif
9412#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009413 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009414#endif
9415#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009416 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009417#endif
9418#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009419 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009420#endif
9421#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009422 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009423#endif
9424#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009425 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009426#endif
9427#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009428 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009429#endif
9430};
9431
9432static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009433conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009434{
9435 return conv_confname(arg, valuep, posix_constants_sysconf,
9436 sizeof(posix_constants_sysconf)
9437 / sizeof(struct constdef));
9438}
9439
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009440PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009441"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009442Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009443
9444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009445posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009446{
9447 PyObject *result = NULL;
9448 int name;
9449
9450 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9451 int value;
9452
9453 errno = 0;
9454 value = sysconf(name);
9455 if (value == -1 && errno != 0)
9456 posix_error();
9457 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009458 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009459 }
9460 return result;
9461}
9462#endif
9463
9464
Fred Drakebec628d1999-12-15 18:31:10 +00009465/* This code is used to ensure that the tables of configuration value names
9466 * are in sorted order as required by conv_confname(), and also to build the
9467 * the exported dictionaries that are used to publish information about the
9468 * names available on the host platform.
9469 *
9470 * Sorting the table at runtime ensures that the table is properly ordered
9471 * when used, even for platforms we're not able to test on. It also makes
9472 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009473 */
Fred Drakebec628d1999-12-15 18:31:10 +00009474
9475static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009476cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009477{
9478 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009479 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009480 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009482
9483 return strcmp(c1->name, c2->name);
9484}
9485
9486static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009487setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009489{
Fred Drakebec628d1999-12-15 18:31:10 +00009490 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009491 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009492
9493 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9494 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009495 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009496 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009497
Barry Warsaw3155db32000-04-13 15:20:40 +00009498 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 PyObject *o = PyLong_FromLong(table[i].value);
9500 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9501 Py_XDECREF(o);
9502 Py_DECREF(d);
9503 return -1;
9504 }
9505 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009506 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009507 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009508}
9509
Fred Drakebec628d1999-12-15 18:31:10 +00009510/* Return -1 on failure, 0 on success. */
9511static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009512setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009513{
9514#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009515 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009516 sizeof(posix_constants_pathconf)
9517 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009518 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009519 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009520#endif
9521#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009522 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009523 sizeof(posix_constants_confstr)
9524 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009525 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009526 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009527#endif
9528#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009529 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009530 sizeof(posix_constants_sysconf)
9531 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009532 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009533 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009534#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009535 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009536}
Fred Draked86ed291999-12-15 15:34:33 +00009537
9538
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009539PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009540"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009541Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009542in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009543
9544static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009545posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009546{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009547 abort();
9548 /*NOTREACHED*/
9549 Py_FatalError("abort() called from Python code didn't abort!");
9550 return NULL;
9551}
Fred Drakebec628d1999-12-15 18:31:10 +00009552
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009553#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009554PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009555"startfile(filepath [, operation]) - Start a file with its associated\n\
9556application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009557\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009558When \"operation\" is not specified or \"open\", this acts like\n\
9559double-clicking the file in Explorer, or giving the file name as an\n\
9560argument to the DOS \"start\" command: the file is opened with whatever\n\
9561application (if any) its extension is associated.\n\
9562When another \"operation\" is given, it specifies what should be done with\n\
9563the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009564\n\
9565startfile returns as soon as the associated application is launched.\n\
9566There is no option to wait for the application to close, and no way\n\
9567to retrieve the application's exit status.\n\
9568\n\
9569The filepath is relative to the current directory. If you want to use\n\
9570an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009571the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009572
9573static PyObject *
9574win32_startfile(PyObject *self, PyObject *args)
9575{
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 PyObject *ofilepath;
9577 char *filepath;
9578 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009579 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009581
Victor Stinnereb5657a2011-09-30 01:44:27 +02009582 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 if (!PyArg_ParseTuple(args, "U|s:startfile",
9584 &unipath, &operation)) {
9585 PyErr_Clear();
9586 goto normal;
9587 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009588
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009590 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009592 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 PyErr_Clear();
9594 operation = NULL;
9595 goto normal;
9596 }
9597 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009598
Victor Stinnereb5657a2011-09-30 01:44:27 +02009599 wpath = PyUnicode_AsUnicode(unipath);
9600 if (wpath == NULL)
9601 goto normal;
9602 if (uoperation) {
9603 woperation = PyUnicode_AsUnicode(uoperation);
9604 if (woperation == NULL)
9605 goto normal;
9606 }
9607 else
9608 woperation = NULL;
9609
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009611 rc = ShellExecuteW((HWND)0, woperation, wpath,
9612 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 Py_END_ALLOW_THREADS
9614
Victor Stinnereb5657a2011-09-30 01:44:27 +02009615 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009617 win32_error_object("startfile", unipath);
9618 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 }
9620 Py_INCREF(Py_None);
9621 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009622
9623normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9625 PyUnicode_FSConverter, &ofilepath,
9626 &operation))
9627 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009628 if (win32_warn_bytes_api()) {
9629 Py_DECREF(ofilepath);
9630 return NULL;
9631 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 filepath = PyBytes_AsString(ofilepath);
9633 Py_BEGIN_ALLOW_THREADS
9634 rc = ShellExecute((HWND)0, operation, filepath,
9635 NULL, NULL, SW_SHOWNORMAL);
9636 Py_END_ALLOW_THREADS
9637 if (rc <= (HINSTANCE)32) {
9638 PyObject *errval = win32_error("startfile", filepath);
9639 Py_DECREF(ofilepath);
9640 return errval;
9641 }
9642 Py_DECREF(ofilepath);
9643 Py_INCREF(Py_None);
9644 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009645}
9646#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009647
Martin v. Löwis438b5342002-12-27 10:16:42 +00009648#ifdef HAVE_GETLOADAVG
9649PyDoc_STRVAR(posix_getloadavg__doc__,
9650"getloadavg() -> (float, float, float)\n\n\
9651Return the number of processes in the system run queue averaged over\n\
9652the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9653was unobtainable");
9654
9655static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009656posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009657{
9658 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009659 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009660 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9661 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009662 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009663 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009664}
9665#endif
9666
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009667PyDoc_STRVAR(device_encoding__doc__,
9668"device_encoding(fd) -> str\n\n\
9669Return a string describing the encoding of the device\n\
9670if the output is a terminal; else return None.");
9671
9672static PyObject *
9673device_encoding(PyObject *self, PyObject *args)
9674{
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009676
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9678 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009679
9680 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009681}
9682
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009683#ifdef HAVE_SETRESUID
9684PyDoc_STRVAR(posix_setresuid__doc__,
9685"setresuid(ruid, euid, suid)\n\n\
9686Set the current process's real, effective, and saved user ids.");
9687
9688static PyObject*
9689posix_setresuid (PyObject *self, PyObject *args)
9690{
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 /* We assume uid_t is no larger than a long. */
9692 long ruid, euid, suid;
9693 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9694 return NULL;
9695 if (setresuid(ruid, euid, suid) < 0)
9696 return posix_error();
9697 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009698}
9699#endif
9700
9701#ifdef HAVE_SETRESGID
9702PyDoc_STRVAR(posix_setresgid__doc__,
9703"setresgid(rgid, egid, sgid)\n\n\
9704Set the current process's real, effective, and saved group ids.");
9705
9706static PyObject*
9707posix_setresgid (PyObject *self, PyObject *args)
9708{
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 /* We assume uid_t is no larger than a long. */
9710 long rgid, egid, sgid;
9711 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9712 return NULL;
9713 if (setresgid(rgid, egid, sgid) < 0)
9714 return posix_error();
9715 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009716}
9717#endif
9718
9719#ifdef HAVE_GETRESUID
9720PyDoc_STRVAR(posix_getresuid__doc__,
9721"getresuid() -> (ruid, euid, suid)\n\n\
9722Get tuple of the current process's real, effective, and saved user ids.");
9723
9724static PyObject*
9725posix_getresuid (PyObject *self, PyObject *noargs)
9726{
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 uid_t ruid, euid, suid;
9728 long l_ruid, l_euid, l_suid;
9729 if (getresuid(&ruid, &euid, &suid) < 0)
9730 return posix_error();
9731 /* Force the values into long's as we don't know the size of uid_t. */
9732 l_ruid = ruid;
9733 l_euid = euid;
9734 l_suid = suid;
9735 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009736}
9737#endif
9738
9739#ifdef HAVE_GETRESGID
9740PyDoc_STRVAR(posix_getresgid__doc__,
9741"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009742Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009743
9744static PyObject*
9745posix_getresgid (PyObject *self, PyObject *noargs)
9746{
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 uid_t rgid, egid, sgid;
9748 long l_rgid, l_egid, l_sgid;
9749 if (getresgid(&rgid, &egid, &sgid) < 0)
9750 return posix_error();
9751 /* Force the values into long's as we don't know the size of uid_t. */
9752 l_rgid = rgid;
9753 l_egid = egid;
9754 l_sgid = sgid;
9755 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009756}
9757#endif
9758
Benjamin Peterson9428d532011-09-14 11:45:52 -04009759#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -04009760
Benjamin Peterson799bd802011-08-31 22:15:17 -04009761PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009762"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
9763Return the value of extended attribute attribute on path.\n\
9764\n\
9765path may be either a string or an open file descriptor.\n\
9766If follow_symlinks is False, and the last element of the path is a symbolic\n\
9767 link, getxattr will examine the symbolic link itself instead of the file\n\
9768 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009769
9770static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009771posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009772{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009773 path_t path;
9774 path_t attribute;
9775 int follow_symlinks = 1;
9776 PyObject *buffer = NULL;
9777 int i;
9778 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009779
Larry Hastings9cf065c2012-06-22 16:30:09 -07009780 memset(&path, 0, sizeof(path));
9781 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009782 path.function_name = "getxattr";
9783 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009784 path.allow_fd = 1;
9785 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
9786 path_converter, &path,
9787 path_converter, &attribute,
9788 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009789 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009790
Larry Hastings9cf065c2012-06-22 16:30:09 -07009791 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
9792 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009793
Larry Hastings9cf065c2012-06-22 16:30:09 -07009794 for (i = 0; ; i++) {
9795 void *ptr;
9796 ssize_t result;
9797 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
9798 Py_ssize_t buffer_size = buffer_sizes[i];
9799 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +01009800 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009801 goto exit;
9802 }
9803 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
9804 if (!buffer)
9805 goto exit;
9806 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009807
Larry Hastings9cf065c2012-06-22 16:30:09 -07009808 Py_BEGIN_ALLOW_THREADS;
9809 if (path.fd >= 0)
9810 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
9811 else if (follow_symlinks)
9812 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9813 else
9814 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9815 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009816
Larry Hastings9cf065c2012-06-22 16:30:09 -07009817 if (result < 0) {
9818 Py_DECREF(buffer);
9819 buffer = NULL;
9820 if (errno == ERANGE)
9821 continue;
Victor Stinner292c8352012-10-30 02:17:38 +01009822 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009823 goto exit;
9824 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009825
Larry Hastings9cf065c2012-06-22 16:30:09 -07009826 if (result != buffer_size) {
9827 /* Can only shrink. */
9828 _PyBytes_Resize(&buffer, result);
9829 }
9830 break;
9831 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009832
Larry Hastings9cf065c2012-06-22 16:30:09 -07009833exit:
9834 path_cleanup(&path);
9835 path_cleanup(&attribute);
9836 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009837}
9838
9839PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009840"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
9841Set extended attribute attribute on path to value.\n\
9842path may be either a string or an open file descriptor.\n\
9843If follow_symlinks is False, and the last element of the path is a symbolic\n\
9844 link, setxattr will modify the symbolic link itself instead of the file\n\
9845 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009846
9847static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009848posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009849{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009850 path_t path;
9851 path_t attribute;
9852 Py_buffer value;
9853 int flags = 0;
9854 int follow_symlinks = 1;
9855 int result;
9856 PyObject *return_value = NULL;
9857 static char *keywords[] = {"path", "attribute", "value",
9858 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009859
Larry Hastings9cf065c2012-06-22 16:30:09 -07009860 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009861 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009862 path.allow_fd = 1;
9863 memset(&attribute, 0, sizeof(attribute));
9864 memset(&value, 0, sizeof(value));
9865 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
9866 keywords,
9867 path_converter, &path,
9868 path_converter, &attribute,
9869 &value, &flags,
9870 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009871 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009872
9873 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
9874 goto exit;
9875
Benjamin Peterson799bd802011-08-31 22:15:17 -04009876 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009877 if (path.fd > -1)
9878 result = fsetxattr(path.fd, attribute.narrow,
9879 value.buf, value.len, flags);
9880 else if (follow_symlinks)
9881 result = setxattr(path.narrow, attribute.narrow,
9882 value.buf, value.len, flags);
9883 else
9884 result = lsetxattr(path.narrow, attribute.narrow,
9885 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009886 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009887
Larry Hastings9cf065c2012-06-22 16:30:09 -07009888 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009889 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009890 goto exit;
9891 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009892
Larry Hastings9cf065c2012-06-22 16:30:09 -07009893 return_value = Py_None;
9894 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009895
Larry Hastings9cf065c2012-06-22 16:30:09 -07009896exit:
9897 path_cleanup(&path);
9898 path_cleanup(&attribute);
9899 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009900
Larry Hastings9cf065c2012-06-22 16:30:09 -07009901 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009902}
9903
9904PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009905"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
9906Remove extended attribute attribute on path.\n\
9907path may be either a string or an open file descriptor.\n\
9908If follow_symlinks is False, and the last element of the path is a symbolic\n\
9909 link, removexattr will modify the symbolic link itself instead of the file\n\
9910 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009911
9912static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009913posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009914{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009915 path_t path;
9916 path_t attribute;
9917 int follow_symlinks = 1;
9918 int result;
9919 PyObject *return_value = NULL;
9920 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009921
Larry Hastings9cf065c2012-06-22 16:30:09 -07009922 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009923 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009924 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009925 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009926 path.allow_fd = 1;
9927 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
9928 keywords,
9929 path_converter, &path,
9930 path_converter, &attribute,
9931 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009932 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009933
9934 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
9935 goto exit;
9936
Benjamin Peterson799bd802011-08-31 22:15:17 -04009937 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009938 if (path.fd > -1)
9939 result = fremovexattr(path.fd, attribute.narrow);
9940 else if (follow_symlinks)
9941 result = removexattr(path.narrow, attribute.narrow);
9942 else
9943 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009944 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009945
Larry Hastings9cf065c2012-06-22 16:30:09 -07009946 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009947 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009948 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009949 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009950
Larry Hastings9cf065c2012-06-22 16:30:09 -07009951 return_value = Py_None;
9952 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009953
Larry Hastings9cf065c2012-06-22 16:30:09 -07009954exit:
9955 path_cleanup(&path);
9956 path_cleanup(&attribute);
9957
9958 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009959}
9960
9961PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009962"listxattr(path='.', *, follow_symlinks=True)\n\n\
9963Return a list of extended attributes on path.\n\
9964\n\
9965path may be either None, a string, or an open file descriptor.\n\
9966if path is None, listxattr will examine the current directory.\n\
9967If follow_symlinks is False, and the last element of the path is a symbolic\n\
9968 link, listxattr will examine the symbolic link itself instead of the file\n\
9969 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009970
9971static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009972posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009973{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009974 path_t path;
9975 int follow_symlinks = 1;
9976 Py_ssize_t i;
9977 PyObject *result = NULL;
9978 char *buffer = NULL;
9979 char *name;
9980 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009981
Larry Hastings9cf065c2012-06-22 16:30:09 -07009982 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009983 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009984 path.allow_fd = 1;
9985 path.fd = -1;
9986 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
9987 path_converter, &path,
9988 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009989 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009990
Larry Hastings9cf065c2012-06-22 16:30:09 -07009991 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
9992 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009993
Larry Hastings9cf065c2012-06-22 16:30:09 -07009994 name = path.narrow ? path.narrow : ".";
9995 for (i = 0; ; i++) {
9996 char *start, *trace, *end;
9997 ssize_t length;
9998 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
9999 Py_ssize_t buffer_size = buffer_sizes[i];
10000 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010001 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010002 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010003 break;
10004 }
10005 buffer = PyMem_MALLOC(buffer_size);
10006 if (!buffer) {
10007 PyErr_NoMemory();
10008 break;
10009 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010010
Larry Hastings9cf065c2012-06-22 16:30:09 -070010011 Py_BEGIN_ALLOW_THREADS;
10012 if (path.fd > -1)
10013 length = flistxattr(path.fd, buffer, buffer_size);
10014 else if (follow_symlinks)
10015 length = listxattr(name, buffer, buffer_size);
10016 else
10017 length = llistxattr(name, buffer, buffer_size);
10018 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010019
Larry Hastings9cf065c2012-06-22 16:30:09 -070010020 if (length < 0) {
10021 if (errno == ERANGE)
10022 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010023 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010024 break;
10025 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010026
Larry Hastings9cf065c2012-06-22 16:30:09 -070010027 result = PyList_New(0);
10028 if (!result) {
10029 goto exit;
10030 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010031
Larry Hastings9cf065c2012-06-22 16:30:09 -070010032 end = buffer + length;
10033 for (trace = start = buffer; trace != end; trace++) {
10034 if (!*trace) {
10035 int error;
10036 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10037 trace - start);
10038 if (!attribute) {
10039 Py_DECREF(result);
10040 result = NULL;
10041 goto exit;
10042 }
10043 error = PyList_Append(result, attribute);
10044 Py_DECREF(attribute);
10045 if (error) {
10046 Py_DECREF(result);
10047 result = NULL;
10048 goto exit;
10049 }
10050 start = trace + 1;
10051 }
10052 }
10053 break;
10054 }
10055exit:
10056 path_cleanup(&path);
10057 if (buffer)
10058 PyMem_FREE(buffer);
10059 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010060}
10061
Benjamin Peterson9428d532011-09-14 11:45:52 -040010062#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010063
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010064
Georg Brandl2fb477c2012-02-21 00:33:36 +010010065PyDoc_STRVAR(posix_urandom__doc__,
10066"urandom(n) -> str\n\n\
10067Return n random bytes suitable for cryptographic use.");
10068
10069static PyObject *
10070posix_urandom(PyObject *self, PyObject *args)
10071{
10072 Py_ssize_t size;
10073 PyObject *result;
10074 int ret;
10075
10076 /* Read arguments */
10077 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10078 return NULL;
10079 if (size < 0)
10080 return PyErr_Format(PyExc_ValueError,
10081 "negative argument not allowed");
10082 result = PyBytes_FromStringAndSize(NULL, size);
10083 if (result == NULL)
10084 return NULL;
10085
10086 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10087 PyBytes_GET_SIZE(result));
10088 if (ret == -1) {
10089 Py_DECREF(result);
10090 return NULL;
10091 }
10092 return result;
10093}
10094
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010095/* Terminal size querying */
10096
10097static PyTypeObject TerminalSizeType;
10098
10099PyDoc_STRVAR(TerminalSize_docstring,
10100 "A tuple of (columns, lines) for holding terminal window size");
10101
10102static PyStructSequence_Field TerminalSize_fields[] = {
10103 {"columns", "width of the terminal window in characters"},
10104 {"lines", "height of the terminal window in characters"},
10105 {NULL, NULL}
10106};
10107
10108static PyStructSequence_Desc TerminalSize_desc = {
10109 "os.terminal_size",
10110 TerminalSize_docstring,
10111 TerminalSize_fields,
10112 2,
10113};
10114
10115#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10116PyDoc_STRVAR(termsize__doc__,
10117 "Return the size of the terminal window as (columns, lines).\n" \
10118 "\n" \
10119 "The optional argument fd (default standard output) specifies\n" \
10120 "which file descriptor should be queried.\n" \
10121 "\n" \
10122 "If the file descriptor is not connected to a terminal, an OSError\n" \
10123 "is thrown.\n" \
10124 "\n" \
10125 "This function will only be defined if an implementation is\n" \
10126 "available for this system.\n" \
10127 "\n" \
10128 "shutil.get_terminal_size is the high-level function which should \n" \
10129 "normally be used, os.get_terminal_size is the low-level implementation.");
10130
10131static PyObject*
10132get_terminal_size(PyObject *self, PyObject *args)
10133{
10134 int columns, lines;
10135 PyObject *termsize;
10136
10137 int fd = fileno(stdout);
10138 /* Under some conditions stdout may not be connected and
10139 * fileno(stdout) may point to an invalid file descriptor. For example
10140 * GUI apps don't have valid standard streams by default.
10141 *
10142 * If this happens, and the optional fd argument is not present,
10143 * the ioctl below will fail returning EBADF. This is what we want.
10144 */
10145
10146 if (!PyArg_ParseTuple(args, "|i", &fd))
10147 return NULL;
10148
10149#ifdef TERMSIZE_USE_IOCTL
10150 {
10151 struct winsize w;
10152 if (ioctl(fd, TIOCGWINSZ, &w))
10153 return PyErr_SetFromErrno(PyExc_OSError);
10154 columns = w.ws_col;
10155 lines = w.ws_row;
10156 }
10157#endif /* TERMSIZE_USE_IOCTL */
10158
10159#ifdef TERMSIZE_USE_CONIO
10160 {
10161 DWORD nhandle;
10162 HANDLE handle;
10163 CONSOLE_SCREEN_BUFFER_INFO csbi;
10164 switch (fd) {
10165 case 0: nhandle = STD_INPUT_HANDLE;
10166 break;
10167 case 1: nhandle = STD_OUTPUT_HANDLE;
10168 break;
10169 case 2: nhandle = STD_ERROR_HANDLE;
10170 break;
10171 default:
10172 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10173 }
10174 handle = GetStdHandle(nhandle);
10175 if (handle == NULL)
10176 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10177 if (handle == INVALID_HANDLE_VALUE)
10178 return PyErr_SetFromWindowsErr(0);
10179
10180 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10181 return PyErr_SetFromWindowsErr(0);
10182
10183 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10184 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10185 }
10186#endif /* TERMSIZE_USE_CONIO */
10187
10188 termsize = PyStructSequence_New(&TerminalSizeType);
10189 if (termsize == NULL)
10190 return NULL;
10191 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10192 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10193 if (PyErr_Occurred()) {
10194 Py_DECREF(termsize);
10195 return NULL;
10196 }
10197 return termsize;
10198}
10199#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10200
10201
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010202static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010203 {"access", (PyCFunction)posix_access,
10204 METH_VARARGS | METH_KEYWORDS,
10205 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010206#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010208#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010209 {"chdir", (PyCFunction)posix_chdir,
10210 METH_VARARGS | METH_KEYWORDS,
10211 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010212#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010213 {"chflags", (PyCFunction)posix_chflags,
10214 METH_VARARGS | METH_KEYWORDS,
10215 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010216#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010217 {"chmod", (PyCFunction)posix_chmod,
10218 METH_VARARGS | METH_KEYWORDS,
10219 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010220#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010222#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010223#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010224 {"chown", (PyCFunction)posix_chown,
10225 METH_VARARGS | METH_KEYWORDS,
10226 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010227#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010228#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010230#endif /* HAVE_LCHMOD */
10231#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010233#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010234#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010236#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010237#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010239#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010240#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010242#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010243#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010245#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010246#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10248 METH_NOARGS, posix_getcwd__doc__},
10249 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10250 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010251#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010252#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10253 {"link", (PyCFunction)posix_link,
10254 METH_VARARGS | METH_KEYWORDS,
10255 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010256#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010257 {"listdir", (PyCFunction)posix_listdir,
10258 METH_VARARGS | METH_KEYWORDS,
10259 posix_listdir__doc__},
10260 {"lstat", (PyCFunction)posix_lstat,
10261 METH_VARARGS | METH_KEYWORDS,
10262 posix_lstat__doc__},
10263 {"mkdir", (PyCFunction)posix_mkdir,
10264 METH_VARARGS | METH_KEYWORDS,
10265 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010266#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010268#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010269#ifdef HAVE_GETPRIORITY
10270 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10271#endif /* HAVE_GETPRIORITY */
10272#ifdef HAVE_SETPRIORITY
10273 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10274#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010275#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010276 {"readlink", (PyCFunction)posix_readlink,
10277 METH_VARARGS | METH_KEYWORDS,
10278 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010279#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010280#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010281 {"readlink", (PyCFunction)win_readlink,
10282 METH_VARARGS | METH_KEYWORDS,
10283 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010284#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010285 {"rename", (PyCFunction)posix_rename,
10286 METH_VARARGS | METH_KEYWORDS,
10287 posix_rename__doc__},
10288 {"replace", (PyCFunction)posix_replace,
10289 METH_VARARGS | METH_KEYWORDS,
10290 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010291 {"rmdir", (PyCFunction)posix_rmdir,
10292 METH_VARARGS | METH_KEYWORDS,
10293 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010294 {"stat", (PyCFunction)posix_stat,
10295 METH_VARARGS | METH_KEYWORDS,
10296 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010298#if defined(HAVE_SYMLINK)
10299 {"symlink", (PyCFunction)posix_symlink,
10300 METH_VARARGS | METH_KEYWORDS,
10301 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010302#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010303#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010305#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010307#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010309#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010310 {"unlink", (PyCFunction)posix_unlink,
10311 METH_VARARGS | METH_KEYWORDS,
10312 posix_unlink__doc__},
10313 {"remove", (PyCFunction)posix_unlink,
10314 METH_VARARGS | METH_KEYWORDS,
10315 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010316 {"utime", (PyCFunction)posix_utime,
10317 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010318#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010320#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010322#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010324 {"execve", (PyCFunction)posix_execve,
10325 METH_VARARGS | METH_KEYWORDS,
10326 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010327#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010328#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10330 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000010331#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010332#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010334#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010335#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010337#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010338#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010339#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010340 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10341 {"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 +020010342#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010343#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010344 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010345#endif
10346#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010347 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010348#endif
10349#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010350 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010351#endif
10352#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010353 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010354#endif
10355#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010356 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010357#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010358 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010359#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010360 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10361 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10362#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010363#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010364#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010366#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010367#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010369#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010370#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010372#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010373#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010375#endif /* HAVE_GETEUID */
10376#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010378#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010379#ifdef HAVE_GETGROUPLIST
10380 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10381#endif
Fred Drakec9680921999-12-13 16:37:25 +000010382#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010386#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010388#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010389#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010390 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010391#endif /* HAVE_GETPPID */
10392#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010393 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010394#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010395#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010397#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010398#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010400#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010401#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010403#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010404#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010406#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010407#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010408 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10409 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010410#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010411#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010413#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010414#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010416#endif /* HAVE_SETEUID */
10417#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010419#endif /* HAVE_SETEGID */
10420#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010422#endif /* HAVE_SETREUID */
10423#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010425#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010426#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010427 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010428#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010429#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010431#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010432#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010434#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010435#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010437#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010438#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010440#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010441#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010443#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010444#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010445 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010446#endif /* HAVE_WAIT3 */
10447#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010448 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010449#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010450#if defined(HAVE_WAITID) && !defined(__APPLE__)
10451 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10452#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010453#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010455#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010456#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010458#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010459#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010460 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010461#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010462#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010464#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010465#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010467#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010468#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010470#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010471 {"open", (PyCFunction)posix_open,\
10472 METH_VARARGS | METH_KEYWORDS,
10473 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010474 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10475 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10476 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10477 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10478 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010479#ifdef HAVE_LOCKF
10480 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10481#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10483 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010484#ifdef HAVE_READV
10485 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10486#endif
10487#ifdef HAVE_PREAD
10488 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10489#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010491#ifdef HAVE_WRITEV
10492 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10493#endif
10494#ifdef HAVE_PWRITE
10495 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10496#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010497#ifdef HAVE_SENDFILE
10498 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10499 posix_sendfile__doc__},
10500#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010501 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010502 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010503#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010504 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010505#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010506#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010507 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010508#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010509#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070010510 {"mkfifo", (PyCFunction)posix_mkfifo,
10511 METH_VARARGS | METH_KEYWORDS,
10512 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010513#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010514#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010515 {"mknod", (PyCFunction)posix_mknod,
10516 METH_VARARGS | METH_KEYWORDS,
10517 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010518#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010519#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10521 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10522 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010523#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010524#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010526#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010527#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020010528 {"truncate", (PyCFunction)posix_truncate,
10529 METH_VARARGS | METH_KEYWORDS,
10530 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010531#endif
10532#ifdef HAVE_POSIX_FALLOCATE
10533 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10534#endif
10535#ifdef HAVE_POSIX_FADVISE
10536 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10537#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010538#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010540#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010541#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010542 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010543#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010544 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010545#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010546 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010547#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010548#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010550#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010551#ifdef HAVE_SYNC
10552 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10553#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010554#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010556#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010557#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010558#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010559 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010560#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010561#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010563#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010564#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010565 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010566#endif /* WIFSTOPPED */
10567#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010568 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010569#endif /* WIFSIGNALED */
10570#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010571 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010572#endif /* WIFEXITED */
10573#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010574 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010575#endif /* WEXITSTATUS */
10576#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010578#endif /* WTERMSIG */
10579#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010581#endif /* WSTOPSIG */
10582#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010583#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010585#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010586#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010587 {"statvfs", (PyCFunction)posix_statvfs,
10588 METH_VARARGS | METH_KEYWORDS,
10589 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010590#endif
Fred Drakec9680921999-12-13 16:37:25 +000010591#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010593#endif
10594#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010596#endif
10597#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010599#endif
10600#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020010601 {"pathconf", (PyCFunction)posix_pathconf,
10602 METH_VARARGS | METH_KEYWORDS,
10603 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010604#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010606#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010608 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010609 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010610 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010611 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010612#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010613#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010614 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010615#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010616 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010617#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010618 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010619#endif
10620#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010622#endif
10623#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010624 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010625#endif
10626#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010627 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010628#endif
10629
Benjamin Peterson9428d532011-09-14 11:45:52 -040010630#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010631 {"setxattr", (PyCFunction)posix_setxattr,
10632 METH_VARARGS | METH_KEYWORDS,
10633 posix_setxattr__doc__},
10634 {"getxattr", (PyCFunction)posix_getxattr,
10635 METH_VARARGS | METH_KEYWORDS,
10636 posix_getxattr__doc__},
10637 {"removexattr", (PyCFunction)posix_removexattr,
10638 METH_VARARGS | METH_KEYWORDS,
10639 posix_removexattr__doc__},
10640 {"listxattr", (PyCFunction)posix_listxattr,
10641 METH_VARARGS | METH_KEYWORDS,
10642 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040010643#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010644#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10645 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
10646#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010647 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010648};
10649
10650
Barry Warsaw4a342091996-12-19 23:50:02 +000010651static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010652ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010653{
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010655}
10656
Brian Curtin52173d42010-12-02 18:29:18 +000010657#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010658static int
Brian Curtin52173d42010-12-02 18:29:18 +000010659enable_symlink()
10660{
10661 HANDLE tok;
10662 TOKEN_PRIVILEGES tok_priv;
10663 LUID luid;
10664 int meth_idx = 0;
10665
10666 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010667 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010668
10669 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010670 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010671
10672 tok_priv.PrivilegeCount = 1;
10673 tok_priv.Privileges[0].Luid = luid;
10674 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
10675
10676 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
10677 sizeof(TOKEN_PRIVILEGES),
10678 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010679 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010680
Brian Curtin3b4499c2010-12-28 14:31:47 +000010681 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
10682 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000010683}
10684#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
10685
Barry Warsaw4a342091996-12-19 23:50:02 +000010686static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000010687all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000010688{
Guido van Rossum94f6f721999-01-06 18:42:14 +000010689#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010690 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010691#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010692#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010694#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010695#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010697#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010698#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010700#endif
Fred Drakec9680921999-12-13 16:37:25 +000010701#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000010703#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010704#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010706#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010707#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010709#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010710#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010712#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010713#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010715#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010716#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010718#endif
10719#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010721#endif
10722#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010724#endif
10725#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010727#endif
10728#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010730#endif
10731#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000010732 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010733#endif
10734#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010736#endif
10737#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010739#endif
10740#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010741 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010742#endif
10743#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010745#endif
10746#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010748#endif
10749#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000010750 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010751#endif
10752#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010753 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010754#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000010755#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010756 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010757#endif
10758#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000010759 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010760#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010761#ifdef O_XATTR
10762 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
10763#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010764#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010766#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000010767#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010768 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010769#endif
10770#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010772#endif
Jesus Ceacf381202012-04-24 20:44:40 +020010773#ifdef O_EXEC
10774 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
10775#endif
10776#ifdef O_SEARCH
10777 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
10778#endif
10779#ifdef O_TTY_INIT
10780 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
10781#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010782#ifdef PRIO_PROCESS
10783 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
10784#endif
10785#ifdef PRIO_PGRP
10786 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
10787#endif
10788#ifdef PRIO_USER
10789 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
10790#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020010791#ifdef O_CLOEXEC
10792 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
10793#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010794#ifdef O_ACCMODE
10795 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
10796#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010797
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010798
Jesus Cea94363612012-06-22 18:32:07 +020010799#ifdef SEEK_HOLE
10800 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
10801#endif
10802#ifdef SEEK_DATA
10803 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
10804#endif
10805
Tim Peters5aa91602002-01-30 05:46:57 +000010806/* MS Windows */
10807#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 /* Don't inherit in child processes. */
10809 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010810#endif
10811#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000010812 /* Optimize for short life (keep in memory). */
10813 /* MS forgot to define this one with a non-underscore form too. */
10814 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010815#endif
10816#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 /* Automatically delete when last handle is closed. */
10818 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010819#endif
10820#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 /* Optimize for random access. */
10822 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010823#endif
10824#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010825 /* Optimize for sequential access. */
10826 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010827#endif
10828
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010829/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010830#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010831 /* Send a SIGIO signal whenever input or output
10832 becomes available on file descriptor */
10833 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010834#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010835#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 /* Direct disk access. */
10837 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010838#endif
10839#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000010840 /* Must be a directory. */
10841 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010842#endif
10843#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 /* Do not follow links. */
10845 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010846#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010847#ifdef O_NOLINKS
10848 /* Fails if link count of the named file is greater than 1 */
10849 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
10850#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010851#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 /* Do not update the access time. */
10853 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010854#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000010855
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010857#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010858 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010859#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010860#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010862#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010863#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010864 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010865#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010866#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010868#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010869#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010871#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010872#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010874#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010875#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010877#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010878#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010880#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010881#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010883#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010884#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010886#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010887#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010889#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010890#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010892#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010893#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010895#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010896#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010898#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010899#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000010900 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010901#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010902#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010904#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010905#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010907#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010908
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010909 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010910#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010911 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010912#endif /* ST_RDONLY */
10913#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000010914 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000010915#endif /* ST_NOSUID */
10916
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010917 /* FreeBSD sendfile() constants */
10918#ifdef SF_NODISKIO
10919 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
10920#endif
10921#ifdef SF_MNOWAIT
10922 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
10923#endif
10924#ifdef SF_SYNC
10925 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
10926#endif
10927
Ross Lagerwall7807c352011-03-17 20:20:30 +020010928 /* constants for posix_fadvise */
10929#ifdef POSIX_FADV_NORMAL
10930 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
10931#endif
10932#ifdef POSIX_FADV_SEQUENTIAL
10933 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
10934#endif
10935#ifdef POSIX_FADV_RANDOM
10936 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
10937#endif
10938#ifdef POSIX_FADV_NOREUSE
10939 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
10940#endif
10941#ifdef POSIX_FADV_WILLNEED
10942 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
10943#endif
10944#ifdef POSIX_FADV_DONTNEED
10945 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
10946#endif
10947
10948 /* constants for waitid */
10949#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
10950 if (ins(d, "P_PID", (long)P_PID)) return -1;
10951 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
10952 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
10953#endif
10954#ifdef WEXITED
10955 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
10956#endif
10957#ifdef WNOWAIT
10958 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
10959#endif
10960#ifdef WSTOPPED
10961 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
10962#endif
10963#ifdef CLD_EXITED
10964 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
10965#endif
10966#ifdef CLD_DUMPED
10967 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
10968#endif
10969#ifdef CLD_TRAPPED
10970 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
10971#endif
10972#ifdef CLD_CONTINUED
10973 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
10974#endif
10975
10976 /* constants for lockf */
10977#ifdef F_LOCK
10978 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
10979#endif
10980#ifdef F_TLOCK
10981 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
10982#endif
10983#ifdef F_ULOCK
10984 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
10985#endif
10986#ifdef F_TEST
10987 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
10988#endif
10989
Guido van Rossum246bc171999-02-01 23:54:31 +000010990#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
10992 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
10993 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
10994 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
10995 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000010996#endif
10997
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010998#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020010999 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011000 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11001 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11002#ifdef SCHED_SPORADIC
11003 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11004#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011005#ifdef SCHED_BATCH
11006 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11007#endif
11008#ifdef SCHED_IDLE
11009 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11010#endif
11011#ifdef SCHED_RESET_ON_FORK
11012 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11013#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011014#ifdef SCHED_SYS
11015 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11016#endif
11017#ifdef SCHED_IA
11018 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11019#endif
11020#ifdef SCHED_FSS
11021 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11022#endif
11023#ifdef SCHED_FX
11024 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11025#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011026#endif
11027
Benjamin Peterson9428d532011-09-14 11:45:52 -040011028#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011029 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11030 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11031 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11032#endif
11033
Victor Stinner8b905bd2011-10-25 13:34:04 +020011034#ifdef RTLD_LAZY
11035 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11036#endif
11037#ifdef RTLD_NOW
11038 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11039#endif
11040#ifdef RTLD_GLOBAL
11041 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11042#endif
11043#ifdef RTLD_LOCAL
11044 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11045#endif
11046#ifdef RTLD_NODELETE
11047 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11048#endif
11049#ifdef RTLD_NOLOAD
11050 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11051#endif
11052#ifdef RTLD_DEEPBIND
11053 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11054#endif
11055
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011057}
11058
11059
Tim Peters5aa91602002-01-30 05:46:57 +000011060#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011061#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011062#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011063
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011064#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011065#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011066#define MODNAME "posix"
11067#endif
11068
Martin v. Löwis1a214512008-06-11 05:26:20 +000011069static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011070 PyModuleDef_HEAD_INIT,
11071 MODNAME,
11072 posix__doc__,
11073 -1,
11074 posix_methods,
11075 NULL,
11076 NULL,
11077 NULL,
11078 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011079};
11080
11081
Larry Hastings9cf065c2012-06-22 16:30:09 -070011082static char *have_functions[] = {
11083
11084#ifdef HAVE_FACCESSAT
11085 "HAVE_FACCESSAT",
11086#endif
11087
11088#ifdef HAVE_FCHDIR
11089 "HAVE_FCHDIR",
11090#endif
11091
11092#ifdef HAVE_FCHMOD
11093 "HAVE_FCHMOD",
11094#endif
11095
11096#ifdef HAVE_FCHMODAT
11097 "HAVE_FCHMODAT",
11098#endif
11099
11100#ifdef HAVE_FCHOWN
11101 "HAVE_FCHOWN",
11102#endif
11103
11104#ifdef HAVE_FEXECVE
11105 "HAVE_FEXECVE",
11106#endif
11107
11108#ifdef HAVE_FDOPENDIR
11109 "HAVE_FDOPENDIR",
11110#endif
11111
Georg Brandl306336b2012-06-24 12:55:33 +020011112#ifdef HAVE_FPATHCONF
11113 "HAVE_FPATHCONF",
11114#endif
11115
Larry Hastings9cf065c2012-06-22 16:30:09 -070011116#ifdef HAVE_FSTATAT
11117 "HAVE_FSTATAT",
11118#endif
11119
11120#ifdef HAVE_FSTATVFS
11121 "HAVE_FSTATVFS",
11122#endif
11123
Georg Brandl306336b2012-06-24 12:55:33 +020011124#ifdef HAVE_FTRUNCATE
11125 "HAVE_FTRUNCATE",
11126#endif
11127
Larry Hastings9cf065c2012-06-22 16:30:09 -070011128#ifdef HAVE_FUTIMENS
11129 "HAVE_FUTIMENS",
11130#endif
11131
11132#ifdef HAVE_FUTIMES
11133 "HAVE_FUTIMES",
11134#endif
11135
11136#ifdef HAVE_FUTIMESAT
11137 "HAVE_FUTIMESAT",
11138#endif
11139
11140#ifdef HAVE_LINKAT
11141 "HAVE_LINKAT",
11142#endif
11143
11144#ifdef HAVE_LCHFLAGS
11145 "HAVE_LCHFLAGS",
11146#endif
11147
11148#ifdef HAVE_LCHMOD
11149 "HAVE_LCHMOD",
11150#endif
11151
11152#ifdef HAVE_LCHOWN
11153 "HAVE_LCHOWN",
11154#endif
11155
11156#ifdef HAVE_LSTAT
11157 "HAVE_LSTAT",
11158#endif
11159
11160#ifdef HAVE_LUTIMES
11161 "HAVE_LUTIMES",
11162#endif
11163
11164#ifdef HAVE_MKDIRAT
11165 "HAVE_MKDIRAT",
11166#endif
11167
11168#ifdef HAVE_MKFIFOAT
11169 "HAVE_MKFIFOAT",
11170#endif
11171
11172#ifdef HAVE_MKNODAT
11173 "HAVE_MKNODAT",
11174#endif
11175
11176#ifdef HAVE_OPENAT
11177 "HAVE_OPENAT",
11178#endif
11179
11180#ifdef HAVE_READLINKAT
11181 "HAVE_READLINKAT",
11182#endif
11183
11184#ifdef HAVE_RENAMEAT
11185 "HAVE_RENAMEAT",
11186#endif
11187
11188#ifdef HAVE_SYMLINKAT
11189 "HAVE_SYMLINKAT",
11190#endif
11191
11192#ifdef HAVE_UNLINKAT
11193 "HAVE_UNLINKAT",
11194#endif
11195
11196#ifdef HAVE_UTIMENSAT
11197 "HAVE_UTIMENSAT",
11198#endif
11199
11200#ifdef MS_WINDOWS
11201 "MS_WINDOWS",
11202#endif
11203
11204 NULL
11205};
11206
11207
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011208PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011209INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011210{
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011212 PyObject *list;
11213 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011214
Brian Curtin52173d42010-12-02 18:29:18 +000011215#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011216 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011217#endif
11218
Victor Stinner8c62be82010-05-06 00:08:46 +000011219 m = PyModule_Create(&posixmodule);
11220 if (m == NULL)
11221 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011222
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 /* Initialize environ dictionary */
11224 v = convertenviron();
11225 Py_XINCREF(v);
11226 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11227 return NULL;
11228 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011229
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 if (all_ins(m))
11231 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011232
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 if (setup_confname_tables(m))
11234 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011235
Victor Stinner8c62be82010-05-06 00:08:46 +000011236 Py_INCREF(PyExc_OSError);
11237 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011238
Guido van Rossumb3d39562000-01-31 18:41:26 +000011239#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011240 if (posix_putenv_garbage == NULL)
11241 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011242#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011243
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011245#if defined(HAVE_WAITID) && !defined(__APPLE__)
11246 waitid_result_desc.name = MODNAME ".waitid_result";
11247 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11248#endif
11249
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 stat_result_desc.name = MODNAME ".stat_result";
11251 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11252 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11253 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11254 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11255 structseq_new = StatResultType.tp_new;
11256 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011257
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 statvfs_result_desc.name = MODNAME ".statvfs_result";
11259 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011260#ifdef NEED_TICKS_PER_SECOND
11261# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011263# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011264 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011265# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011266 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011267# endif
11268#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011269
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011270#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011271 sched_param_desc.name = MODNAME ".sched_param";
11272 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11273 SchedParamType.tp_new = sched_param_new;
11274#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011275
11276 /* initialize TerminalSize_info */
11277 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011278 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011279#if defined(HAVE_WAITID) && !defined(__APPLE__)
11280 Py_INCREF((PyObject*) &WaitidResultType);
11281 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11282#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 Py_INCREF((PyObject*) &StatResultType);
11284 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11285 Py_INCREF((PyObject*) &StatVFSResultType);
11286 PyModule_AddObject(m, "statvfs_result",
11287 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011288
11289#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011290 Py_INCREF(&SchedParamType);
11291 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011292#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011293
Larry Hastings605a62d2012-06-24 04:33:36 -070011294 times_result_desc.name = MODNAME ".times_result";
11295 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11296 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11297
11298 uname_result_desc.name = MODNAME ".uname_result";
11299 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11300 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11301
Thomas Wouters477c8d52006-05-27 19:21:47 +000011302#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 /*
11304 * Step 2 of weak-linking support on Mac OS X.
11305 *
11306 * The code below removes functions that are not available on the
11307 * currently active platform.
11308 *
11309 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011310 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011311 * OSX 10.4.
11312 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011313#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011314 if (fstatvfs == NULL) {
11315 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11316 return NULL;
11317 }
11318 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011319#endif /* HAVE_FSTATVFS */
11320
11321#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 if (statvfs == NULL) {
11323 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11324 return NULL;
11325 }
11326 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011327#endif /* HAVE_STATVFS */
11328
11329# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011330 if (lchown == NULL) {
11331 if (PyObject_DelAttrString(m, "lchown") == -1) {
11332 return NULL;
11333 }
11334 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011335#endif /* HAVE_LCHOWN */
11336
11337
11338#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011339
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011340 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011341 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11342
Larry Hastings6fe20b32012-04-19 15:07:49 -070011343 billion = PyLong_FromLong(1000000000);
11344 if (!billion)
11345 return NULL;
11346
Larry Hastings9cf065c2012-06-22 16:30:09 -070011347 /* suppress "function not used" warnings */
11348 {
11349 int ignored;
11350 fd_specified("", -1);
11351 follow_symlinks_specified("", 1);
11352 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11353 dir_fd_converter(Py_None, &ignored);
11354 dir_fd_unavailable(Py_None, &ignored);
11355 }
11356
11357 /*
11358 * provide list of locally available functions
11359 * so os.py can populate support_* lists
11360 */
11361 list = PyList_New(0);
11362 if (!list)
11363 return NULL;
11364 for (trace = have_functions; *trace; trace++) {
11365 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11366 if (!unicode)
11367 return NULL;
11368 if (PyList_Append(list, unicode))
11369 return NULL;
11370 Py_DECREF(unicode);
11371 }
11372 PyModule_AddObject(m, "_have_functions", list);
11373
11374 initialized = 1;
11375
Victor Stinner8c62be82010-05-06 00:08:46 +000011376 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011377
Guido van Rossumb6775db1994-08-01 11:34:53 +000011378}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011379
11380#ifdef __cplusplus
11381}
11382#endif