blob: 1149856e3055db01103d5ec61cd535d97936e027 [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"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020026#ifndef MS_WINDOWS
27#include "posixmodule.h"
28#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020031# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Ross Lagerwall4d076da2011-03-18 06:56:53 +020046#ifdef HAVE_SYS_UIO_H
47#include <sys/uio.h>
48#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#endif /* HAVE_SYS_TYPES_H */
53
54#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000055#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000057
Guido van Rossum36bc6801995-06-14 22:54:23 +000058#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000059#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000063#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000065
Guido van Rossumb6775db1994-08-01 11:34:53 +000066#ifdef HAVE_FCNTL_H
67#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000068#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070#ifdef HAVE_GRP_H
71#include <grp.h>
72#endif
73
Barry Warsaw5676bd12003-01-07 20:57:09 +000074#ifdef HAVE_SYSEXITS_H
75#include <sysexits.h>
76#endif /* HAVE_SYSEXITS_H */
77
Anthony Baxter8a560de2004-10-13 15:30:56 +000078#ifdef HAVE_SYS_LOADAVG_H
79#include <sys/loadavg.h>
80#endif
81
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000082#ifdef HAVE_LANGINFO_H
83#include <langinfo.h>
84#endif
85
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000086#ifdef HAVE_SYS_SENDFILE_H
87#include <sys/sendfile.h>
88#endif
89
Benjamin Peterson94b580d2011-08-02 17:30:04 -050090#ifdef HAVE_SCHED_H
91#include <sched.h>
92#endif
93
Benjamin Peterson2dbda072012-03-16 10:12:55 -050094#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050095#undef HAVE_SCHED_SETAFFINITY
96#endif
97
Benjamin Peterson9428d532011-09-14 11:45:52 -040098#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
99#define USE_XATTRS
100#endif
101
102#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400103#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400104#endif
105
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000106#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
107#ifdef HAVE_SYS_SOCKET_H
108#include <sys/socket.h>
109#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000110#endif
111
Victor Stinner8b905bd2011-10-25 13:34:04 +0200112#ifdef HAVE_DLFCN_H
113#include <dlfcn.h>
114#endif
115
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100116#if defined(MS_WINDOWS)
117# define TERMSIZE_USE_CONIO
118#elif defined(HAVE_SYS_IOCTL_H)
119# include <sys/ioctl.h>
120# if defined(HAVE_TERMIOS_H)
121# include <termios.h>
122# endif
123# if defined(TIOCGWINSZ)
124# define TERMSIZE_USE_IOCTL
125# endif
126#endif /* MS_WINDOWS */
127
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000129/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000130#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000131#define HAVE_GETCWD 1
132#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000133#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#include <process.h>
135#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000136#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#define HAVE_EXECV 1
138#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#define HAVE_OPENDIR 1
140#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000141#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#define HAVE_WAIT 1
143#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000145#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000146#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000147#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_EXECV 1
150#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#define HAVE_SYSTEM 1
152#define HAVE_CWAIT 1
153#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000154#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000155#else
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200156#if defined(__VMS)
157/* Everything needed is defined in vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000158#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159/* Unix functions that the configure script doesn't check for */
160#define HAVE_EXECV 1
161#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000163#define HAVE_FORK1 1
164#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_GETCWD 1
166#define HAVE_GETEGID 1
167#define HAVE_GETEUID 1
168#define HAVE_GETGID 1
169#define HAVE_GETPPID 1
170#define HAVE_GETUID 1
171#define HAVE_KILL 1
172#define HAVE_OPENDIR 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000176#define HAVE_TTYNAME 1
Jesus Ceaab70e2a2012-10-05 01:48:08 +0200177#endif /* __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#endif /* _MSC_VER */
179#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000180#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000181
Victor Stinnera2f7c002012-02-08 03:36:25 +0100182
183
184
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000186
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000187#if defined(__sgi)&&_COMPILER_VERSION>=700
188/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
189 (default) */
190extern char *ctermid_r(char *);
191#endif
192
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000193#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000194#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000196#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000197#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000198extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#endif
203#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int chdir(char *);
205extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000207extern int chdir(const char *);
208extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000209#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000210#ifdef __BORLANDC__
211extern int chmod(const char *, int);
212#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000213extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000214#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000215/*#ifdef HAVE_FCHMOD
216extern int fchmod(int, mode_t);
217#endif*/
218/*#ifdef HAVE_LCHMOD
219extern int lchmod(const char *, mode_t);
220#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chown(const char *, uid_t, gid_t);
222extern char *getcwd(char *, int);
223extern char *strerror(int);
224extern int link(const char *, const char *);
225extern int rename(const char *, const char *);
226extern int stat(const char *, struct stat *);
227extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000229extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000230#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000232extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000235
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#ifdef HAVE_UTIME_H
239#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000240#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000242#ifdef HAVE_SYS_UTIME_H
243#include <sys/utime.h>
244#define HAVE_UTIME_H /* pretend we do for the rest of this file */
245#endif /* HAVE_SYS_UTIME_H */
246
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#ifdef HAVE_SYS_TIMES_H
248#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000249#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250
251#ifdef HAVE_SYS_PARAM_H
252#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
255#ifdef HAVE_SYS_UTSNAME_H
256#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000259#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000261#define NAMLEN(dirent) strlen((dirent)->d_name)
262#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000263#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000264#include <direct.h>
265#define NAMLEN(dirent) strlen((dirent)->d_name)
266#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000268#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000270#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#endif
273#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000275#endif
276#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#endif
279#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000281#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000282#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000283#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000284#endif
285#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000287#endif
288#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000289#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000291#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000292#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000293#endif
294#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000295#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000296#endif
297#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000298#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000299#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000300#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000301#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000302#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000303#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000304#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000305#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
306#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000307static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000308#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000309#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310
Tim Petersbc2e10e2002-03-03 23:17:02 +0000311#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000312#if defined(PATH_MAX) && PATH_MAX > 1024
313#define MAXPATHLEN PATH_MAX
314#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000315#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000317#endif /* MAXPATHLEN */
318
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000319#ifdef UNION_WAIT
320/* Emulate some macros on systems that have a union instead of macros */
321
322#ifndef WIFEXITED
323#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
324#endif
325
326#ifndef WEXITSTATUS
327#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
328#endif
329
330#ifndef WTERMSIG
331#define WTERMSIG(u_wait) ((u_wait).w_termsig)
332#endif
333
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000334#define WAIT_TYPE union wait
335#define WAIT_STATUS_INT(s) (s.w_status)
336
337#else /* !UNION_WAIT */
338#define WAIT_TYPE int
339#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000340#endif /* UNION_WAIT */
341
Greg Wardb48bc172000-03-01 21:51:56 +0000342/* Don't use the "_r" form if we don't need it (also, won't have a
343 prototype for it, at least on Solaris -- maybe others as well?). */
344#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
345#define USE_CTERMID_R
346#endif
347
Fred Drake699f3522000-06-29 21:12:41 +0000348/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000349#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000350#undef FSTAT
351#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000352#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000353# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700354# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000355# define FSTAT win32_fstat
356# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000357#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000358# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700359# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000360# define FSTAT fstat
361# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000362#endif
363
Tim Peters11b23062003-04-23 02:39:17 +0000364#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000365#include <sys/mkdev.h>
366#else
367#if defined(MAJOR_IN_SYSMACROS)
368#include <sys/sysmacros.h>
369#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000370#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
371#include <sys/mkdev.h>
372#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000373#endif
Fred Drake699f3522000-06-29 21:12:41 +0000374
Larry Hastings9cf065c2012-06-22 16:30:09 -0700375
376#ifdef MS_WINDOWS
377static int
378win32_warn_bytes_api()
379{
380 return PyErr_WarnEx(PyExc_DeprecationWarning,
381 "The Windows bytes API has been deprecated, "
382 "use Unicode filenames instead",
383 1);
384}
385#endif
386
387
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200388#ifndef MS_WINDOWS
389PyObject *
390_PyLong_FromUid(uid_t uid)
391{
392 if (uid == (uid_t)-1)
393 return PyLong_FromLong(-1);
394 return PyLong_FromUnsignedLong(uid);
395}
396
397PyObject *
398_PyLong_FromGid(gid_t gid)
399{
400 if (gid == (gid_t)-1)
401 return PyLong_FromLong(-1);
402 return PyLong_FromUnsignedLong(gid);
403}
404
405int
406_Py_Uid_Converter(PyObject *obj, void *p)
407{
408 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200409 long result;
410 if (PyFloat_Check(obj)) {
411 PyErr_SetString(PyExc_TypeError,
412 "integer argument expected, got float");
413 return 0;
414 }
415 result = PyLong_AsLongAndOverflow(obj, &overflow);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200416 if (overflow < 0)
417 goto OverflowDown;
418 if (!overflow && result == -1) {
419 /* error or -1 */
420 if (PyErr_Occurred())
421 return 0;
422 *(uid_t *)p = (uid_t)-1;
423 }
424 else {
425 /* unsigned uid_t */
426 unsigned long uresult;
427 if (overflow > 0) {
428 uresult = PyLong_AsUnsignedLong(obj);
429 if (PyErr_Occurred()) {
430 if (PyErr_ExceptionMatches(PyExc_OverflowError))
431 goto OverflowUp;
432 return 0;
433 }
434 if ((uid_t)uresult == (uid_t)-1)
435 goto OverflowUp;
436 } else {
437 if (result < 0)
438 goto OverflowDown;
439 uresult = result;
440 }
441 if (sizeof(uid_t) < sizeof(long) &&
442 (unsigned long)(uid_t)uresult != uresult)
443 goto OverflowUp;
444 *(uid_t *)p = (uid_t)uresult;
445 }
446 return 1;
447
448OverflowDown:
449 PyErr_SetString(PyExc_OverflowError,
450 "user id is less than minimum");
451 return 0;
452
453OverflowUp:
454 PyErr_SetString(PyExc_OverflowError,
455 "user id is greater than maximum");
456 return 0;
457}
458
459int
460_Py_Gid_Converter(PyObject *obj, void *p)
461{
462 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200463 long result;
464 if (PyFloat_Check(obj)) {
465 PyErr_SetString(PyExc_TypeError,
466 "integer argument expected, got float");
467 return 0;
468 }
469 result = PyLong_AsLongAndOverflow(obj, &overflow);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200470 if (overflow < 0)
471 goto OverflowDown;
472 if (!overflow && result == -1) {
473 /* error or -1 */
474 if (PyErr_Occurred())
475 return 0;
476 *(gid_t *)p = (gid_t)-1;
477 }
478 else {
479 /* unsigned gid_t */
480 unsigned long uresult;
481 if (overflow > 0) {
482 uresult = PyLong_AsUnsignedLong(obj);
483 if (PyErr_Occurred()) {
484 if (PyErr_ExceptionMatches(PyExc_OverflowError))
485 goto OverflowUp;
486 return 0;
487 }
488 if ((gid_t)uresult == (gid_t)-1)
489 goto OverflowUp;
490 } else {
491 if (result < 0)
492 goto OverflowDown;
493 uresult = result;
494 }
495 if (sizeof(gid_t) < sizeof(long) &&
496 (unsigned long)(gid_t)uresult != uresult)
497 goto OverflowUp;
498 *(gid_t *)p = (gid_t)uresult;
499 }
500 return 1;
501
502OverflowDown:
503 PyErr_SetString(PyExc_OverflowError,
504 "group id is less than minimum");
505 return 0;
506
507OverflowUp:
508 PyErr_SetString(PyExc_OverflowError,
509 "group id is greater than maximum");
510 return 0;
511}
512#endif /* MS_WINDOWS */
513
514
Larry Hastings9cf065c2012-06-22 16:30:09 -0700515#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400516/*
517 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
518 * without the int cast, the value gets interpreted as uint (4291925331),
519 * which doesn't play nicely with all the initializer lines in this file that
520 * look like this:
521 * int dir_fd = DEFAULT_DIR_FD;
522 */
523#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700524#else
525#define DEFAULT_DIR_FD (-100)
526#endif
527
528static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200529_fd_converter(PyObject *o, int *p, const char *allowed)
530{
531 int overflow;
532 long long_value = PyLong_AsLongAndOverflow(o, &overflow);
533 if (PyFloat_Check(o) ||
534 (long_value == -1 && !overflow && PyErr_Occurred())) {
535 PyErr_Clear();
536 PyErr_Format(PyExc_TypeError,
537 "argument should be %s, not %.200s",
538 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700539 return 0;
540 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200541 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700542 PyErr_SetString(PyExc_OverflowError,
543 "signed integer is greater than maximum");
544 return 0;
545 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200546 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700547 PyErr_SetString(PyExc_OverflowError,
548 "signed integer is less than minimum");
549 return 0;
550 }
551 *p = (int)long_value;
552 return 1;
553}
554
555static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200556dir_fd_converter(PyObject *o, void *p)
557{
558 if (o == Py_None) {
559 *(int *)p = DEFAULT_DIR_FD;
560 return 1;
561 }
562 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700563}
564
565
566
567/*
568 * A PyArg_ParseTuple "converter" function
569 * that handles filesystem paths in the manner
570 * preferred by the os module.
571 *
572 * path_converter accepts (Unicode) strings and their
573 * subclasses, and bytes and their subclasses. What
574 * it does with the argument depends on the platform:
575 *
576 * * On Windows, if we get a (Unicode) string we
577 * extract the wchar_t * and return it; if we get
578 * bytes we extract the char * and return that.
579 *
580 * * On all other platforms, strings are encoded
581 * to bytes using PyUnicode_FSConverter, then we
582 * extract the char * from the bytes object and
583 * return that.
584 *
585 * path_converter also optionally accepts signed
586 * integers (representing open file descriptors) instead
587 * of path strings.
588 *
589 * Input fields:
590 * path.nullable
591 * If nonzero, the path is permitted to be None.
592 * path.allow_fd
593 * If nonzero, the path is permitted to be a file handle
594 * (a signed int) instead of a string.
595 * path.function_name
596 * If non-NULL, path_converter will use that as the name
597 * of the function in error messages.
598 * (If path.argument_name is NULL it omits the function name.)
599 * path.argument_name
600 * If non-NULL, path_converter will use that as the name
601 * of the parameter in error messages.
602 * (If path.argument_name is NULL it uses "path".)
603 *
604 * Output fields:
605 * path.wide
606 * Points to the path if it was expressed as Unicode
607 * and was not encoded. (Only used on Windows.)
608 * path.narrow
609 * Points to the path if it was expressed as bytes,
610 * or it was Unicode and was encoded to bytes.
611 * path.fd
612 * Contains a file descriptor if path.accept_fd was true
613 * and the caller provided a signed integer instead of any
614 * sort of string.
615 *
616 * WARNING: if your "path" parameter is optional, and is
617 * unspecified, path_converter will never get called.
618 * So if you set allow_fd, you *MUST* initialize path.fd = -1
619 * yourself!
620 * path.length
621 * The length of the path in characters, if specified as
622 * a string.
623 * path.object
624 * The original object passed in.
625 * path.cleanup
626 * For internal use only. May point to a temporary object.
627 * (Pay no attention to the man behind the curtain.)
628 *
629 * At most one of path.wide or path.narrow will be non-NULL.
630 * If path was None and path.nullable was set,
631 * or if path was an integer and path.allow_fd was set,
632 * both path.wide and path.narrow will be NULL
633 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200634 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700635 * path_converter takes care to not write to the path_t
636 * unless it's successful. However it must reset the
637 * "cleanup" field each time it's called.
638 *
639 * Use as follows:
640 * path_t path;
641 * memset(&path, 0, sizeof(path));
642 * PyArg_ParseTuple(args, "O&", path_converter, &path);
643 * // ... use values from path ...
644 * path_cleanup(&path);
645 *
646 * (Note that if PyArg_Parse fails you don't need to call
647 * path_cleanup(). However it is safe to do so.)
648 */
649typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100650 const char *function_name;
651 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700652 int nullable;
653 int allow_fd;
654 wchar_t *wide;
655 char *narrow;
656 int fd;
657 Py_ssize_t length;
658 PyObject *object;
659 PyObject *cleanup;
660} path_t;
661
662static void
663path_cleanup(path_t *path) {
664 if (path->cleanup) {
665 Py_DECREF(path->cleanup);
666 path->cleanup = NULL;
667 }
668}
669
670static int
671path_converter(PyObject *o, void *p) {
672 path_t *path = (path_t *)p;
673 PyObject *unicode, *bytes;
674 Py_ssize_t length;
675 char *narrow;
676
677#define FORMAT_EXCEPTION(exc, fmt) \
678 PyErr_Format(exc, "%s%s" fmt, \
679 path->function_name ? path->function_name : "", \
680 path->function_name ? ": " : "", \
681 path->argument_name ? path->argument_name : "path")
682
683 /* Py_CLEANUP_SUPPORTED support */
684 if (o == NULL) {
685 path_cleanup(path);
686 return 1;
687 }
688
689 /* ensure it's always safe to call path_cleanup() */
690 path->cleanup = NULL;
691
692 if (o == Py_None) {
693 if (!path->nullable) {
694 FORMAT_EXCEPTION(PyExc_TypeError,
695 "can't specify None for %s argument");
696 return 0;
697 }
698 path->wide = NULL;
699 path->narrow = NULL;
700 path->length = 0;
701 path->object = o;
702 path->fd = -1;
703 return 1;
704 }
705
706 unicode = PyUnicode_FromObject(o);
707 if (unicode) {
708#ifdef MS_WINDOWS
709 wchar_t *wide;
710 length = PyUnicode_GET_SIZE(unicode);
711 if (length > 32767) {
712 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
713 Py_DECREF(unicode);
714 return 0;
715 }
716
717 wide = PyUnicode_AsUnicode(unicode);
718 if (!wide) {
719 Py_DECREF(unicode);
720 return 0;
721 }
722
723 path->wide = wide;
724 path->narrow = NULL;
725 path->length = length;
726 path->object = o;
727 path->fd = -1;
728 path->cleanup = unicode;
729 return Py_CLEANUP_SUPPORTED;
730#else
731 int converted = PyUnicode_FSConverter(unicode, &bytes);
732 Py_DECREF(unicode);
733 if (!converted)
734 bytes = NULL;
735#endif
736 }
737 else {
738 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200739 if (PyObject_CheckBuffer(o))
740 bytes = PyBytes_FromObject(o);
741 else
742 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700743 if (!bytes) {
744 PyErr_Clear();
745 if (path->allow_fd) {
746 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200747 int result = _fd_converter(o, &fd,
748 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700749 if (result) {
750 path->wide = NULL;
751 path->narrow = NULL;
752 path->length = 0;
753 path->object = o;
754 path->fd = fd;
755 return result;
756 }
757 }
758 }
759 }
760
761 if (!bytes) {
762 if (!PyErr_Occurred())
763 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
764 return 0;
765 }
766
767#ifdef MS_WINDOWS
768 if (win32_warn_bytes_api()) {
769 Py_DECREF(bytes);
770 return 0;
771 }
772#endif
773
774 length = PyBytes_GET_SIZE(bytes);
775#ifdef MS_WINDOWS
776 if (length > MAX_PATH) {
777 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
778 Py_DECREF(bytes);
779 return 0;
780 }
781#endif
782
783 narrow = PyBytes_AS_STRING(bytes);
784 if (length != strlen(narrow)) {
785 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
786 Py_DECREF(bytes);
787 return 0;
788 }
789
790 path->wide = NULL;
791 path->narrow = narrow;
792 path->length = length;
793 path->object = o;
794 path->fd = -1;
795 path->cleanup = bytes;
796 return Py_CLEANUP_SUPPORTED;
797}
798
799static void
800argument_unavailable_error(char *function_name, char *argument_name) {
801 PyErr_Format(PyExc_NotImplementedError,
802 "%s%s%s unavailable on this platform",
803 (function_name != NULL) ? function_name : "",
804 (function_name != NULL) ? ": ": "",
805 argument_name);
806}
807
808static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200809dir_fd_unavailable(PyObject *o, void *p)
810{
811 int dir_fd;
812 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700813 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200814 if (dir_fd != DEFAULT_DIR_FD) {
815 argument_unavailable_error(NULL, "dir_fd");
816 return 0;
817 }
818 *(int *)p = dir_fd;
819 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700820}
821
822static int
823fd_specified(char *function_name, int fd) {
824 if (fd == -1)
825 return 0;
826
827 argument_unavailable_error(function_name, "fd");
828 return 1;
829}
830
831static int
832follow_symlinks_specified(char *function_name, int follow_symlinks) {
833 if (follow_symlinks)
834 return 0;
835
836 argument_unavailable_error(function_name, "follow_symlinks");
837 return 1;
838}
839
840static int
841path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
842 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
843 PyErr_Format(PyExc_ValueError,
844 "%s: can't specify dir_fd without matching path",
845 function_name);
846 return 1;
847 }
848 return 0;
849}
850
851static int
852dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
853 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
854 PyErr_Format(PyExc_ValueError,
855 "%s: can't specify both dir_fd and fd",
856 function_name);
857 return 1;
858 }
859 return 0;
860}
861
862static int
863fd_and_follow_symlinks_invalid(char *function_name, int fd,
864 int follow_symlinks) {
865 if ((fd > 0) && (!follow_symlinks)) {
866 PyErr_Format(PyExc_ValueError,
867 "%s: cannot use fd and follow_symlinks together",
868 function_name);
869 return 1;
870 }
871 return 0;
872}
873
874static int
875dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
876 int follow_symlinks) {
877 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
878 PyErr_Format(PyExc_ValueError,
879 "%s: cannot use dir_fd and follow_symlinks together",
880 function_name);
881 return 1;
882 }
883 return 0;
884}
885
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200886/* A helper used by a number of POSIX-only functions */
887#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000888static int
889_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000890{
891#if !defined(HAVE_LARGEFILE_SUPPORT)
892 *((off_t*)addr) = PyLong_AsLong(arg);
893#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000894 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000895#endif
896 if (PyErr_Occurred())
897 return 0;
898 return 1;
899}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200900#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000901
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000902#if defined _MSC_VER && _MSC_VER >= 1400
903/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200904 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000905 * Normally, an invalid fd is likely to be a C program error and therefore
906 * an assertion can be useful, but it does contradict the POSIX standard
907 * which for write(2) states:
908 * "Otherwise, -1 shall be returned and errno set to indicate the error."
909 * "[EBADF] The fildes argument is not a valid file descriptor open for
910 * writing."
911 * Furthermore, python allows the user to enter any old integer
912 * as a fd and should merely raise a python exception on error.
913 * The Microsoft CRT doesn't provide an official way to check for the
914 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000915 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000916 * internal structures involved.
917 * The structures below must be updated for each version of visual studio
918 * according to the file internal.h in the CRT source, until MS comes
919 * up with a less hacky way to do this.
920 * (all of this is to avoid globally modifying the CRT behaviour using
921 * _set_invalid_parameter_handler() and _CrtSetReportMode())
922 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000923/* The actual size of the structure is determined at runtime.
924 * Only the first items must be present.
925 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000926typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000927 intptr_t osfhnd;
928 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000929} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000930
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000931extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000932#define IOINFO_L2E 5
933#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
934#define IOINFO_ARRAYS 64
935#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
936#define FOPEN 0x01
937#define _NO_CONSOLE_FILENO (intptr_t)-2
938
939/* This function emulates what the windows CRT does to validate file handles */
940int
941_PyVerify_fd(int fd)
942{
Victor Stinner8c62be82010-05-06 00:08:46 +0000943 const int i1 = fd >> IOINFO_L2E;
944 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000945
Antoine Pitrou22e41552010-08-15 18:07:50 +0000946 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000947
Victor Stinner8c62be82010-05-06 00:08:46 +0000948 /* Determine the actual size of the ioinfo structure,
949 * as used by the CRT loaded in memory
950 */
951 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
952 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
953 }
954 if (sizeof_ioinfo == 0) {
955 /* This should not happen... */
956 goto fail;
957 }
958
959 /* See that it isn't a special CLEAR fileno */
960 if (fd != _NO_CONSOLE_FILENO) {
961 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
962 * we check pointer validity and other info
963 */
964 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
965 /* finally, check that the file is open */
966 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
967 if (info->osfile & FOPEN) {
968 return 1;
969 }
970 }
971 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000972 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000973 errno = EBADF;
974 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000975}
976
977/* the special case of checking dup2. The target fd must be in a sensible range */
978static int
979_PyVerify_fd_dup2(int fd1, int fd2)
980{
Victor Stinner8c62be82010-05-06 00:08:46 +0000981 if (!_PyVerify_fd(fd1))
982 return 0;
983 if (fd2 == _NO_CONSOLE_FILENO)
984 return 0;
985 if ((unsigned)fd2 < _NHANDLE_)
986 return 1;
987 else
988 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000989}
990#else
991/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
992#define _PyVerify_fd_dup2(A, B) (1)
993#endif
994
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000995#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000996/* The following structure was copied from
997 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
998 include doesn't seem to be present in the Windows SDK (at least as included
999 with Visual Studio Express). */
1000typedef struct _REPARSE_DATA_BUFFER {
1001 ULONG ReparseTag;
1002 USHORT ReparseDataLength;
1003 USHORT Reserved;
1004 union {
1005 struct {
1006 USHORT SubstituteNameOffset;
1007 USHORT SubstituteNameLength;
1008 USHORT PrintNameOffset;
1009 USHORT PrintNameLength;
1010 ULONG Flags;
1011 WCHAR PathBuffer[1];
1012 } SymbolicLinkReparseBuffer;
1013
1014 struct {
1015 USHORT SubstituteNameOffset;
1016 USHORT SubstituteNameLength;
1017 USHORT PrintNameOffset;
1018 USHORT PrintNameLength;
1019 WCHAR PathBuffer[1];
1020 } MountPointReparseBuffer;
1021
1022 struct {
1023 UCHAR DataBuffer[1];
1024 } GenericReparseBuffer;
1025 };
1026} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1027
1028#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1029 GenericReparseBuffer)
1030#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1031
1032static int
Brian Curtind25aef52011-06-13 15:16:04 -05001033win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001034{
1035 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1036 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1037 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001038
1039 if (0 == DeviceIoControl(
1040 reparse_point_handle,
1041 FSCTL_GET_REPARSE_POINT,
1042 NULL, 0, /* in buffer */
1043 target_buffer, sizeof(target_buffer),
1044 &n_bytes_returned,
1045 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001046 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001047
1048 if (reparse_tag)
1049 *reparse_tag = rdb->ReparseTag;
1050
Brian Curtind25aef52011-06-13 15:16:04 -05001051 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001052}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001053
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001054#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001055
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001056/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001057#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001058/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001059** environ directly, we must obtain it with _NSGetEnviron(). See also
1060** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001061*/
1062#include <crt_externs.h>
1063static char **environ;
1064#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001065extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001066#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001067
Barry Warsaw53699e91996-12-10 23:23:01 +00001068static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001069convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001070{
Victor Stinner8c62be82010-05-06 00:08:46 +00001071 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001072#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001073 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001074#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001075 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001076#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001077
Victor Stinner8c62be82010-05-06 00:08:46 +00001078 d = PyDict_New();
1079 if (d == NULL)
1080 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001081#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001082 if (environ == NULL)
1083 environ = *_NSGetEnviron();
1084#endif
1085#ifdef MS_WINDOWS
1086 /* _wenviron must be initialized in this way if the program is started
1087 through main() instead of wmain(). */
1088 _wgetenv(L"");
1089 if (_wenviron == NULL)
1090 return d;
1091 /* This part ignores errors */
1092 for (e = _wenviron; *e != NULL; e++) {
1093 PyObject *k;
1094 PyObject *v;
1095 wchar_t *p = wcschr(*e, L'=');
1096 if (p == NULL)
1097 continue;
1098 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1099 if (k == NULL) {
1100 PyErr_Clear();
1101 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001102 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001103 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1104 if (v == NULL) {
1105 PyErr_Clear();
1106 Py_DECREF(k);
1107 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001108 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001109 if (PyDict_GetItem(d, k) == NULL) {
1110 if (PyDict_SetItem(d, k, v) != 0)
1111 PyErr_Clear();
1112 }
1113 Py_DECREF(k);
1114 Py_DECREF(v);
1115 }
1116#else
1117 if (environ == NULL)
1118 return d;
1119 /* This part ignores errors */
1120 for (e = environ; *e != NULL; e++) {
1121 PyObject *k;
1122 PyObject *v;
1123 char *p = strchr(*e, '=');
1124 if (p == NULL)
1125 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001126 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001127 if (k == NULL) {
1128 PyErr_Clear();
1129 continue;
1130 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001131 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001132 if (v == NULL) {
1133 PyErr_Clear();
1134 Py_DECREF(k);
1135 continue;
1136 }
1137 if (PyDict_GetItem(d, k) == NULL) {
1138 if (PyDict_SetItem(d, k, v) != 0)
1139 PyErr_Clear();
1140 }
1141 Py_DECREF(k);
1142 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001143 }
1144#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001145 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001146}
1147
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001148/* Set a POSIX-specific error from errno, and return NULL */
1149
Barry Warsawd58d7641998-07-23 16:14:40 +00001150static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001151posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001152{
Victor Stinner8c62be82010-05-06 00:08:46 +00001153 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001154}
Mark Hammondef8b6542001-05-13 08:04:26 +00001155
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001156#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001157static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001158win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001159{
Victor Stinner8c62be82010-05-06 00:08:46 +00001160 /* XXX We should pass the function name along in the future.
1161 (winreg.c also wants to pass the function name.)
1162 This would however require an additional param to the
1163 Windows error object, which is non-trivial.
1164 */
1165 errno = GetLastError();
1166 if (filename)
1167 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1168 else
1169 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001170}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001171
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001172static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001173win32_error_object(char* function, PyObject* filename)
1174{
1175 /* XXX - see win32_error for comments on 'function' */
1176 errno = GetLastError();
1177 if (filename)
1178 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001179 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001180 errno,
1181 filename);
1182 else
1183 return PyErr_SetFromWindowsErr(errno);
1184}
1185
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001186#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001187
Larry Hastings9cf065c2012-06-22 16:30:09 -07001188static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001189path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001190{
1191#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001192 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1193 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001194#else
Victor Stinner292c8352012-10-30 02:17:38 +01001195 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001196#endif
1197}
1198
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001199/* POSIX generic methods */
1200
Barry Warsaw53699e91996-12-10 23:23:01 +00001201static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001202posix_fildes(PyObject *fdobj, int (*func)(int))
1203{
Victor Stinner8c62be82010-05-06 00:08:46 +00001204 int fd;
1205 int res;
1206 fd = PyObject_AsFileDescriptor(fdobj);
1207 if (fd < 0)
1208 return NULL;
1209 if (!_PyVerify_fd(fd))
1210 return posix_error();
1211 Py_BEGIN_ALLOW_THREADS
1212 res = (*func)(fd);
1213 Py_END_ALLOW_THREADS
1214 if (res < 0)
1215 return posix_error();
1216 Py_INCREF(Py_None);
1217 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001218}
Guido van Rossum21142a01999-01-08 21:05:37 +00001219
1220static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001221posix_1str(const char *func_name, PyObject *args, char *format,
1222 int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001223{
Victor Stinner292c8352012-10-30 02:17:38 +01001224 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01001226 memset(&path, 0, sizeof(path));
1227 path.function_name = func_name;
Victor Stinner8c62be82010-05-06 00:08:46 +00001228 if (!PyArg_ParseTuple(args, format,
Victor Stinner292c8352012-10-30 02:17:38 +01001229 path_converter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00001230 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001231 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001232 res = (*func)(path.narrow);
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01001234 if (res < 0) {
1235 path_error(&path);
1236 path_cleanup(&path);
1237 return NULL;
1238 }
1239 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001240 Py_INCREF(Py_None);
1241 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001242}
1243
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001244
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001245#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001246/* This is a reimplementation of the C library's chdir function,
1247 but one that produces Win32 errors instead of DOS error codes.
1248 chdir is essentially a wrapper around SetCurrentDirectory; however,
1249 it also needs to set "magic" environment variables indicating
1250 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001251static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001252win32_chdir(LPCSTR path)
1253{
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 char new_path[MAX_PATH+1];
1255 int result;
1256 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001257
Victor Stinner8c62be82010-05-06 00:08:46 +00001258 if(!SetCurrentDirectoryA(path))
1259 return FALSE;
1260 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1261 if (!result)
1262 return FALSE;
1263 /* In the ANSI API, there should not be any paths longer
1264 than MAX_PATH. */
1265 assert(result <= MAX_PATH+1);
1266 if (strncmp(new_path, "\\\\", 2) == 0 ||
1267 strncmp(new_path, "//", 2) == 0)
1268 /* UNC path, nothing to do. */
1269 return TRUE;
1270 env[1] = new_path[0];
1271 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001272}
1273
1274/* The Unicode version differs from the ANSI version
1275 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001276static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001277win32_wchdir(LPCWSTR path)
1278{
Victor Stinner8c62be82010-05-06 00:08:46 +00001279 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1280 int result;
1281 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001282
Victor Stinner8c62be82010-05-06 00:08:46 +00001283 if(!SetCurrentDirectoryW(path))
1284 return FALSE;
1285 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1286 if (!result)
1287 return FALSE;
1288 if (result > MAX_PATH+1) {
1289 new_path = malloc(result * sizeof(wchar_t));
1290 if (!new_path) {
1291 SetLastError(ERROR_OUTOFMEMORY);
1292 return FALSE;
1293 }
1294 result = GetCurrentDirectoryW(result, new_path);
1295 if (!result) {
1296 free(new_path);
1297 return FALSE;
1298 }
1299 }
1300 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1301 wcsncmp(new_path, L"//", 2) == 0)
1302 /* UNC path, nothing to do. */
1303 return TRUE;
1304 env[1] = new_path[0];
1305 result = SetEnvironmentVariableW(env, new_path);
1306 if (new_path != _new_path)
1307 free(new_path);
1308 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001309}
1310#endif
1311
Martin v. Löwis14694662006-02-03 12:54:16 +00001312#ifdef MS_WINDOWS
1313/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1314 - time stamps are restricted to second resolution
1315 - file modification times suffer from forth-and-back conversions between
1316 UTC and local time
1317 Therefore, we implement our own stat, based on the Win32 API directly.
1318*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001319#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001320
1321struct win32_stat{
Brian Curtin87e63a22012-12-31 11:59:48 -06001322 unsigned long st_dev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001323 __int64 st_ino;
1324 unsigned short st_mode;
1325 int st_nlink;
1326 int st_uid;
1327 int st_gid;
Brian Curtin87e63a22012-12-31 11:59:48 -06001328 unsigned long st_rdev;
Martin v. Löwis14694662006-02-03 12:54:16 +00001329 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001330 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001331 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001332 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001333 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001334 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001335 int st_ctime_nsec;
1336};
1337
1338static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1339
1340static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001341FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001342{
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1344 /* Cannot simply cast and dereference in_ptr,
1345 since it might not be aligned properly */
1346 __int64 in;
1347 memcpy(&in, in_ptr, sizeof(in));
1348 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001349 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001350}
1351
Thomas Wouters477c8d52006-05-27 19:21:47 +00001352static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001353time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001354{
Victor Stinner8c62be82010-05-06 00:08:46 +00001355 /* XXX endianness */
1356 __int64 out;
1357 out = time_in + secs_between_epochs;
1358 out = out * 10000000 + nsec_in / 100;
1359 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001360}
1361
Martin v. Löwis14694662006-02-03 12:54:16 +00001362/* Below, we *know* that ugo+r is 0444 */
1363#if _S_IREAD != 0400
1364#error Unsupported C library
1365#endif
1366static int
1367attributes_to_mode(DWORD attr)
1368{
Victor Stinner8c62be82010-05-06 00:08:46 +00001369 int m = 0;
1370 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1371 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1372 else
1373 m |= _S_IFREG;
1374 if (attr & FILE_ATTRIBUTE_READONLY)
1375 m |= 0444;
1376 else
1377 m |= 0666;
1378 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001379}
1380
1381static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001382attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001383{
Victor Stinner8c62be82010-05-06 00:08:46 +00001384 memset(result, 0, sizeof(*result));
1385 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1386 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
Brian Curtin490b32a2012-12-26 07:03:03 -06001387 result->st_dev = info->dwVolumeSerialNumber;
1388 result->st_rdev = result->st_dev;
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1390 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1391 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001392 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001393 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001394 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1395 /* first clear the S_IFMT bits */
1396 result->st_mode ^= (result->st_mode & 0170000);
1397 /* now set the bits that make this a symlink */
1398 result->st_mode |= 0120000;
1399 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001400
Victor Stinner8c62be82010-05-06 00:08:46 +00001401 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001402}
1403
Guido van Rossumd8faa362007-04-27 19:54:29 +00001404static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001405attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001406{
Victor Stinner8c62be82010-05-06 00:08:46 +00001407 HANDLE hFindFile;
1408 WIN32_FIND_DATAA FileData;
1409 hFindFile = FindFirstFileA(pszFile, &FileData);
1410 if (hFindFile == INVALID_HANDLE_VALUE)
1411 return FALSE;
1412 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001413 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001414 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001415 info->dwFileAttributes = FileData.dwFileAttributes;
1416 info->ftCreationTime = FileData.ftCreationTime;
1417 info->ftLastAccessTime = FileData.ftLastAccessTime;
1418 info->ftLastWriteTime = FileData.ftLastWriteTime;
1419 info->nFileSizeHigh = FileData.nFileSizeHigh;
1420 info->nFileSizeLow = FileData.nFileSizeLow;
1421/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001422 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1423 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001425}
1426
1427static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001428attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001429{
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 HANDLE hFindFile;
1431 WIN32_FIND_DATAW FileData;
1432 hFindFile = FindFirstFileW(pszFile, &FileData);
1433 if (hFindFile == INVALID_HANDLE_VALUE)
1434 return FALSE;
1435 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001436 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001437 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001438 info->dwFileAttributes = FileData.dwFileAttributes;
1439 info->ftCreationTime = FileData.ftCreationTime;
1440 info->ftLastAccessTime = FileData.ftLastAccessTime;
1441 info->ftLastWriteTime = FileData.ftLastWriteTime;
1442 info->nFileSizeHigh = FileData.nFileSizeHigh;
1443 info->nFileSizeLow = FileData.nFileSizeLow;
1444/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001445 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1446 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001447 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001448}
1449
Brian Curtind25aef52011-06-13 15:16:04 -05001450/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001451static int has_GetFinalPathNameByHandle = -1;
Brian Curtind25aef52011-06-13 15:16:04 -05001452static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1453 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001454static int
Brian Curtind25aef52011-06-13 15:16:04 -05001455check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001456{
Brian Curtind25aef52011-06-13 15:16:04 -05001457 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001458 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1459 DWORD);
1460
Brian Curtind25aef52011-06-13 15:16:04 -05001461 /* only recheck */
Antoine Pitrou06eecea2012-10-21 16:33:33 +02001462 if (-1 == has_GetFinalPathNameByHandle)
Brian Curtind25aef52011-06-13 15:16:04 -05001463 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001464 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001465 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1466 "GetFinalPathNameByHandleA");
1467 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1468 "GetFinalPathNameByHandleW");
1469 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1470 Py_GetFinalPathNameByHandleW;
1471 }
1472 return has_GetFinalPathNameByHandle;
1473}
1474
1475static BOOL
1476get_target_path(HANDLE hdl, wchar_t **target_path)
1477{
1478 int buf_size, result_length;
1479 wchar_t *buf;
1480
1481 /* We have a good handle to the target, use it to determine
1482 the target path name (then we'll call lstat on it). */
1483 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1484 VOLUME_NAME_DOS);
1485 if(!buf_size)
1486 return FALSE;
1487
1488 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001489 if (!buf) {
1490 SetLastError(ERROR_OUTOFMEMORY);
1491 return FALSE;
1492 }
1493
Brian Curtind25aef52011-06-13 15:16:04 -05001494 result_length = Py_GetFinalPathNameByHandleW(hdl,
1495 buf, buf_size, VOLUME_NAME_DOS);
1496
1497 if(!result_length) {
1498 free(buf);
1499 return FALSE;
1500 }
1501
1502 if(!CloseHandle(hdl)) {
1503 free(buf);
1504 return FALSE;
1505 }
1506
1507 buf[result_length] = 0;
1508
1509 *target_path = buf;
1510 return TRUE;
1511}
1512
1513static int
1514win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1515 BOOL traverse);
1516static int
1517win32_xstat_impl(const char *path, struct win32_stat *result,
1518 BOOL traverse)
1519{
Victor Stinner26de69d2011-06-17 15:15:38 +02001520 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001521 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001522 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001523 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001524 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001525 const char *dot;
1526
Brian Curtind25aef52011-06-13 15:16:04 -05001527 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001528 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1529 traverse reparse point. */
1530 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001531 }
1532
Brian Curtinf5e76d02010-11-24 13:14:05 +00001533 hFile = CreateFileA(
1534 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001535 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001536 0, /* share mode */
1537 NULL, /* security attributes */
1538 OPEN_EXISTING,
1539 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001540 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1541 Because of this, calls like GetFinalPathNameByHandle will return
1542 the symlink path agin and not the actual final path. */
1543 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1544 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001545 NULL);
1546
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001547 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001548 /* Either the target doesn't exist, or we don't have access to
1549 get a handle to it. If the former, we need to return an error.
1550 If the latter, we can use attributes_from_dir. */
1551 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001552 return -1;
1553 /* Could not get attributes on open file. Fall back to
1554 reading the directory. */
1555 if (!attributes_from_dir(path, &info, &reparse_tag))
1556 /* Very strange. This should not fail now */
1557 return -1;
1558 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1559 if (traverse) {
1560 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001561 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001562 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001563 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001564 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001565 } else {
1566 if (!GetFileInformationByHandle(hFile, &info)) {
1567 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001568 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001569 }
1570 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001571 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1572 return -1;
1573
1574 /* Close the outer open file handle now that we're about to
1575 reopen it with different flags. */
1576 if (!CloseHandle(hFile))
1577 return -1;
1578
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001579 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001580 /* In order to call GetFinalPathNameByHandle we need to open
1581 the file without the reparse handling flag set. */
1582 hFile2 = CreateFileA(
1583 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1584 NULL, OPEN_EXISTING,
1585 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1586 NULL);
1587 if (hFile2 == INVALID_HANDLE_VALUE)
1588 return -1;
1589
1590 if (!get_target_path(hFile2, &target_path))
1591 return -1;
1592
1593 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001594 free(target_path);
1595 return code;
1596 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001597 } else
1598 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001599 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001600 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001601
1602 /* Set S_IEXEC if it is an .exe, .bat, ... */
1603 dot = strrchr(path, '.');
1604 if (dot) {
1605 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1606 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1607 result->st_mode |= 0111;
1608 }
1609 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001610}
1611
1612static int
Brian Curtind25aef52011-06-13 15:16:04 -05001613win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1614 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001615{
1616 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001617 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001618 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001619 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001620 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001621 const wchar_t *dot;
1622
Brian Curtind25aef52011-06-13 15:16:04 -05001623 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001624 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1625 traverse reparse point. */
1626 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001627 }
1628
Brian Curtinf5e76d02010-11-24 13:14:05 +00001629 hFile = CreateFileW(
1630 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001631 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001632 0, /* share mode */
1633 NULL, /* security attributes */
1634 OPEN_EXISTING,
1635 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001636 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1637 Because of this, calls like GetFinalPathNameByHandle will return
1638 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001639 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001640 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001641 NULL);
1642
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001643 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001644 /* Either the target doesn't exist, or we don't have access to
1645 get a handle to it. If the former, we need to return an error.
1646 If the latter, we can use attributes_from_dir. */
1647 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001648 return -1;
1649 /* Could not get attributes on open file. Fall back to
1650 reading the directory. */
1651 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1652 /* Very strange. This should not fail now */
1653 return -1;
1654 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1655 if (traverse) {
1656 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001657 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001658 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 } else {
1662 if (!GetFileInformationByHandle(hFile, &info)) {
1663 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001664 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001665 }
1666 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001667 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1668 return -1;
1669
1670 /* Close the outer open file handle now that we're about to
1671 reopen it with different flags. */
1672 if (!CloseHandle(hFile))
1673 return -1;
1674
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001675 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001676 /* In order to call GetFinalPathNameByHandle we need to open
1677 the file without the reparse handling flag set. */
1678 hFile2 = CreateFileW(
1679 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1680 NULL, OPEN_EXISTING,
1681 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1682 NULL);
1683 if (hFile2 == INVALID_HANDLE_VALUE)
1684 return -1;
1685
1686 if (!get_target_path(hFile2, &target_path))
1687 return -1;
1688
1689 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001690 free(target_path);
1691 return code;
1692 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001693 } else
1694 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001695 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001696 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001697
1698 /* Set S_IEXEC if it is an .exe, .bat, ... */
1699 dot = wcsrchr(path, '.');
1700 if (dot) {
1701 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1702 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1703 result->st_mode |= 0111;
1704 }
1705 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001706}
1707
1708static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001710{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001711 /* Protocol violation: we explicitly clear errno, instead of
1712 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001713 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001714 errno = 0;
1715 return code;
1716}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001717
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001718static int
1719win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1720{
1721 /* Protocol violation: we explicitly clear errno, instead of
1722 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001723 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001724 errno = 0;
1725 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001726}
Brian Curtind25aef52011-06-13 15:16:04 -05001727/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001728
1729 In Posix, stat automatically traverses symlinks and returns the stat
1730 structure for the target. In Windows, the equivalent GetFileAttributes by
1731 default does not traverse symlinks and instead returns attributes for
1732 the symlink.
1733
1734 Therefore, win32_lstat will get the attributes traditionally, and
1735 win32_stat will first explicitly resolve the symlink target and then will
1736 call win32_lstat on that result.
1737
Ezio Melotti4969f702011-03-15 05:59:46 +02001738 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001739
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001740static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001741win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001742{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001743 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001744}
1745
Victor Stinner8c62be82010-05-06 00:08:46 +00001746static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001747win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001748{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001749 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001750}
1751
1752static int
1753win32_stat(const char* path, struct win32_stat *result)
1754{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001755 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001756}
1757
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001758static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001759win32_stat_w(const wchar_t* path, struct win32_stat *result)
1760{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001761 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001762}
1763
1764static int
1765win32_fstat(int file_number, struct win32_stat *result)
1766{
Victor Stinner8c62be82010-05-06 00:08:46 +00001767 BY_HANDLE_FILE_INFORMATION info;
1768 HANDLE h;
1769 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001770
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001771 if (!_PyVerify_fd(file_number))
1772 h = INVALID_HANDLE_VALUE;
1773 else
1774 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001775
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 /* Protocol violation: we explicitly clear errno, instead of
1777 setting it to a POSIX error. Callers should use GetLastError. */
1778 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001779
Victor Stinner8c62be82010-05-06 00:08:46 +00001780 if (h == INVALID_HANDLE_VALUE) {
1781 /* This is really a C library error (invalid file handle).
1782 We set the Win32 error to the closes one matching. */
1783 SetLastError(ERROR_INVALID_HANDLE);
1784 return -1;
1785 }
1786 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001787
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 type = GetFileType(h);
1789 if (type == FILE_TYPE_UNKNOWN) {
1790 DWORD error = GetLastError();
1791 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001792 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001793 }
1794 /* else: valid but unknown file */
1795 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001796
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 if (type != FILE_TYPE_DISK) {
1798 if (type == FILE_TYPE_CHAR)
1799 result->st_mode = _S_IFCHR;
1800 else if (type == FILE_TYPE_PIPE)
1801 result->st_mode = _S_IFIFO;
1802 return 0;
1803 }
1804
1805 if (!GetFileInformationByHandle(h, &info)) {
1806 return -1;
1807 }
1808
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001809 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001810 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001811 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1812 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001813}
1814
1815#endif /* MS_WINDOWS */
1816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001818"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001819This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001820 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001821or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1822\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001823Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1824or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001825\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001826See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001827
1828static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001829 {"st_mode", "protection bits"},
1830 {"st_ino", "inode"},
1831 {"st_dev", "device"},
1832 {"st_nlink", "number of hard links"},
1833 {"st_uid", "user ID of owner"},
1834 {"st_gid", "group ID of owner"},
1835 {"st_size", "total size, in bytes"},
1836 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1837 {NULL, "integer time of last access"},
1838 {NULL, "integer time of last modification"},
1839 {NULL, "integer time of last change"},
1840 {"st_atime", "time of last access"},
1841 {"st_mtime", "time of last modification"},
1842 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001843 {"st_atime_ns", "time of last access in nanoseconds"},
1844 {"st_mtime_ns", "time of last modification in nanoseconds"},
1845 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001846#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001848#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001849#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001851#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001852#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001853 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001854#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001855#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001856 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001857#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001858#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001860#endif
1861#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001862 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001863#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001864 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001865};
1866
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001867#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001868#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001869#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001870#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001871#endif
1872
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001873#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001874#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1875#else
1876#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1877#endif
1878
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001879#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001880#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1881#else
1882#define ST_RDEV_IDX ST_BLOCKS_IDX
1883#endif
1884
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001885#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1886#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1887#else
1888#define ST_FLAGS_IDX ST_RDEV_IDX
1889#endif
1890
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001891#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001892#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001893#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001894#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001895#endif
1896
1897#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1898#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1899#else
1900#define ST_BIRTHTIME_IDX ST_GEN_IDX
1901#endif
1902
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001903static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001904 "stat_result", /* name */
1905 stat_result__doc__, /* doc */
1906 stat_result_fields,
1907 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001908};
1909
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001910PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001911"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1912This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001913 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001914or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001915\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001916See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001917
1918static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 {"f_bsize", },
1920 {"f_frsize", },
1921 {"f_blocks", },
1922 {"f_bfree", },
1923 {"f_bavail", },
1924 {"f_files", },
1925 {"f_ffree", },
1926 {"f_favail", },
1927 {"f_flag", },
1928 {"f_namemax",},
1929 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001930};
1931
1932static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 "statvfs_result", /* name */
1934 statvfs_result__doc__, /* doc */
1935 statvfs_result_fields,
1936 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001937};
1938
Ross Lagerwall7807c352011-03-17 20:20:30 +02001939#if defined(HAVE_WAITID) && !defined(__APPLE__)
1940PyDoc_STRVAR(waitid_result__doc__,
1941"waitid_result: Result from waitid.\n\n\
1942This object may be accessed either as a tuple of\n\
1943 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1944or via the attributes si_pid, si_uid, and so on.\n\
1945\n\
1946See os.waitid for more information.");
1947
1948static PyStructSequence_Field waitid_result_fields[] = {
1949 {"si_pid", },
1950 {"si_uid", },
1951 {"si_signo", },
1952 {"si_status", },
1953 {"si_code", },
1954 {0}
1955};
1956
1957static PyStructSequence_Desc waitid_result_desc = {
1958 "waitid_result", /* name */
1959 waitid_result__doc__, /* doc */
1960 waitid_result_fields,
1961 5
1962};
1963static PyTypeObject WaitidResultType;
1964#endif
1965
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001966static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001967static PyTypeObject StatResultType;
1968static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001969#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001970static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001971#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001972static newfunc structseq_new;
1973
1974static PyObject *
1975statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1976{
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 PyStructSequence *result;
1978 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001979
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 result = (PyStructSequence*)structseq_new(type, args, kwds);
1981 if (!result)
1982 return NULL;
1983 /* If we have been initialized from a tuple,
1984 st_?time might be set to None. Initialize it
1985 from the int slots. */
1986 for (i = 7; i <= 9; i++) {
1987 if (result->ob_item[i+3] == Py_None) {
1988 Py_DECREF(Py_None);
1989 Py_INCREF(result->ob_item[i]);
1990 result->ob_item[i+3] = result->ob_item[i];
1991 }
1992 }
1993 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001994}
1995
1996
1997
1998/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001999static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002000
2001PyDoc_STRVAR(stat_float_times__doc__,
2002"stat_float_times([newval]) -> oldval\n\n\
2003Determine whether os.[lf]stat represents time stamps as float objects.\n\
2004If newval is True, future calls to stat() return floats, if it is False,\n\
2005future calls return ints. \n\
2006If newval is omitted, return the current setting.\n");
2007
2008static PyObject*
2009stat_float_times(PyObject* self, PyObject *args)
2010{
Victor Stinner8c62be82010-05-06 00:08:46 +00002011 int newval = -1;
2012 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2013 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002014 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2015 "stat_float_times() is deprecated",
2016 1))
2017 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002018 if (newval == -1)
2019 /* Return old value */
2020 return PyBool_FromLong(_stat_float_times);
2021 _stat_float_times = newval;
2022 Py_INCREF(Py_None);
2023 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002024}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002025
Larry Hastings6fe20b32012-04-19 15:07:49 -07002026static PyObject *billion = NULL;
2027
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002028static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002029fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002030{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002031 PyObject *s = _PyLong_FromTime_t(sec);
2032 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2033 PyObject *s_in_ns = NULL;
2034 PyObject *ns_total = NULL;
2035 PyObject *float_s = NULL;
2036
2037 if (!(s && ns_fractional))
2038 goto exit;
2039
2040 s_in_ns = PyNumber_Multiply(s, billion);
2041 if (!s_in_ns)
2042 goto exit;
2043
2044 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2045 if (!ns_total)
2046 goto exit;
2047
Victor Stinner4195b5c2012-02-08 23:03:19 +01002048 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002049 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2050 if (!float_s)
2051 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002053 else {
2054 float_s = s;
2055 Py_INCREF(float_s);
2056 }
2057
2058 PyStructSequence_SET_ITEM(v, index, s);
2059 PyStructSequence_SET_ITEM(v, index+3, float_s);
2060 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2061 s = NULL;
2062 float_s = NULL;
2063 ns_total = NULL;
2064exit:
2065 Py_XDECREF(s);
2066 Py_XDECREF(ns_fractional);
2067 Py_XDECREF(s_in_ns);
2068 Py_XDECREF(ns_total);
2069 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002070}
2071
Tim Peters5aa91602002-01-30 05:46:57 +00002072/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002073 (used by posix_stat() and posix_fstat()) */
2074static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002075_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002076{
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 unsigned long ansec, mnsec, cnsec;
2078 PyObject *v = PyStructSequence_New(&StatResultType);
2079 if (v == NULL)
2080 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002081
Victor Stinner8c62be82010-05-06 00:08:46 +00002082 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002083#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 PyStructSequence_SET_ITEM(v, 1,
2085 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002086#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002087 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002088#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002089#ifdef MS_WINDOWS
2090 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
2091#elif defined(HAVE_LONG_LONG)
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 PyStructSequence_SET_ITEM(v, 2,
2093 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002094#else
Brian Curtin9cc43212013-01-01 12:31:06 -06002095 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002096#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002097 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002098#if defined(MS_WINDOWS)
2099 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2100 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2101#else
2102 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2103 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2104#endif
Fred Drake699f3522000-06-29 21:12:41 +00002105#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002106 PyStructSequence_SET_ITEM(v, 6,
2107 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002108#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002109 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002110#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002111
Martin v. Löwis14694662006-02-03 12:54:16 +00002112#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 ansec = st->st_atim.tv_nsec;
2114 mnsec = st->st_mtim.tv_nsec;
2115 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002116#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002117 ansec = st->st_atimespec.tv_nsec;
2118 mnsec = st->st_mtimespec.tv_nsec;
2119 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002120#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002121 ansec = st->st_atime_nsec;
2122 mnsec = st->st_mtime_nsec;
2123 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002124#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002125 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002126#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002127 fill_time(v, 7, st->st_atime, ansec);
2128 fill_time(v, 8, st->st_mtime, mnsec);
2129 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002130
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002131#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002132 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2133 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002134#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002135#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002136 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2137 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002138#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002139#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2141 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002142#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002143#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002144 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2145 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002146#endif
2147#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002148 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002149 PyObject *val;
2150 unsigned long bsec,bnsec;
2151 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002152#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002153 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002154#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002155 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002156#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002157 if (_stat_float_times) {
2158 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2159 } else {
2160 val = PyLong_FromLong((long)bsec);
2161 }
2162 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2163 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002164 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002165#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002166#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002167 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2168 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002169#endif
Fred Drake699f3522000-06-29 21:12:41 +00002170
Victor Stinner8c62be82010-05-06 00:08:46 +00002171 if (PyErr_Occurred()) {
2172 Py_DECREF(v);
2173 return NULL;
2174 }
Fred Drake699f3522000-06-29 21:12:41 +00002175
Victor Stinner8c62be82010-05-06 00:08:46 +00002176 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002177}
2178
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002179/* POSIX methods */
2180
Guido van Rossum94f6f721999-01-06 18:42:14 +00002181
2182static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002183posix_do_stat(char *function_name, path_t *path,
2184 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002185{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002186 STRUCT_STAT st;
2187 int result;
2188
2189#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2190 if (follow_symlinks_specified(function_name, follow_symlinks))
2191 return NULL;
2192#endif
2193
2194 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2195 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2196 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2197 return NULL;
2198
2199 Py_BEGIN_ALLOW_THREADS
2200 if (path->fd != -1)
2201 result = FSTAT(path->fd, &st);
2202 else
2203#ifdef MS_WINDOWS
2204 if (path->wide) {
2205 if (follow_symlinks)
2206 result = win32_stat_w(path->wide, &st);
2207 else
2208 result = win32_lstat_w(path->wide, &st);
2209 }
2210 else
2211#endif
2212#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2213 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2214 result = LSTAT(path->narrow, &st);
2215 else
2216#endif
2217#ifdef HAVE_FSTATAT
2218 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2219 result = fstatat(dir_fd, path->narrow, &st,
2220 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2221 else
2222#endif
2223 result = STAT(path->narrow, &st);
2224 Py_END_ALLOW_THREADS
2225
Victor Stinner292c8352012-10-30 02:17:38 +01002226 if (result != 0) {
2227 return path_error(path);
2228 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002229
2230 return _pystat_fromstructstat(&st);
2231}
2232
2233PyDoc_STRVAR(posix_stat__doc__,
2234"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2235Perform a stat system call on the given path.\n\
2236\n\
2237path may be specified as either a string or as an open file descriptor.\n\
2238\n\
2239If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2240 and path should be relative; path will then be relative to that directory.\n\
2241 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2242 it will raise a NotImplementedError.\n\
2243If follow_symlinks is False, and the last element of the path is a symbolic\n\
2244 link, stat will examine the symbolic link itself instead of the file the\n\
2245 link points to.\n\
2246It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2247 an open file descriptor.");
2248
2249static PyObject *
2250posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2251{
2252 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2253 path_t path;
2254 int dir_fd = DEFAULT_DIR_FD;
2255 int follow_symlinks = 1;
2256 PyObject *return_value;
2257
2258 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002259 path.function_name = "stat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002260 path.allow_fd = 1;
2261 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2262 path_converter, &path,
2263#ifdef HAVE_FSTATAT
2264 dir_fd_converter, &dir_fd,
2265#else
2266 dir_fd_unavailable, &dir_fd,
2267#endif
2268 &follow_symlinks))
2269 return NULL;
2270 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2271 path_cleanup(&path);
2272 return return_value;
2273}
2274
2275PyDoc_STRVAR(posix_lstat__doc__,
2276"lstat(path, *, dir_fd=None) -> stat result\n\n\
2277Like stat(), but do not follow symbolic links.\n\
2278Equivalent to stat(path, follow_symlinks=False).");
2279
2280static PyObject *
2281posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2282{
2283 static char *keywords[] = {"path", "dir_fd", NULL};
2284 path_t path;
2285 int dir_fd = DEFAULT_DIR_FD;
2286 int follow_symlinks = 0;
2287 PyObject *return_value;
2288
2289 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002290 path.function_name = "lstat";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002291 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2292 path_converter, &path,
2293#ifdef HAVE_FSTATAT
2294 dir_fd_converter, &dir_fd
2295#else
2296 dir_fd_unavailable, &dir_fd
2297#endif
2298 ))
2299 return NULL;
2300 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2301 path_cleanup(&path);
2302 return return_value;
2303}
2304
2305PyDoc_STRVAR(posix_access__doc__,
2306"access(path, mode, *, dir_fd=None, effective_ids=False,\
2307 follow_symlinks=True)\n\n\
2308Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2309False otherwise.\n\
2310\n\
2311If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2312 and path should be relative; path will then be relative to that directory.\n\
2313If effective_ids is True, access will use the effective uid/gid instead of\n\
2314 the real uid/gid.\n\
2315If follow_symlinks is False, and the last element of the path is a symbolic\n\
2316 link, access will examine the symbolic link itself instead of the file the\n\
2317 link points to.\n\
2318dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2319 on your platform. If they are unavailable, using them will raise a\n\
2320 NotImplementedError.\n\
2321\n\
2322Note that most operations will use the effective uid/gid, therefore this\n\
2323 routine can be used in a suid/sgid environment to test if the invoking user\n\
2324 has the specified access to the path.\n\
2325The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2326 of R_OK, W_OK, and X_OK.");
2327
2328static PyObject *
2329posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2330{
2331 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2332 "follow_symlinks", NULL};
2333 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002334 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002335 int dir_fd = DEFAULT_DIR_FD;
2336 int effective_ids = 0;
2337 int follow_symlinks = 1;
2338 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002339
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002340#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002341 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002342#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002343 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002344#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002345
2346 memset(&path, 0, sizeof(path));
2347 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2348 path_converter, &path, &mode,
2349#ifdef HAVE_FACCESSAT
2350 dir_fd_converter, &dir_fd,
2351#else
2352 dir_fd_unavailable, &dir_fd,
2353#endif
2354 &effective_ids, &follow_symlinks))
2355 return NULL;
2356
2357#ifndef HAVE_FACCESSAT
2358 if (follow_symlinks_specified("access", follow_symlinks))
2359 goto exit;
2360
2361 if (effective_ids) {
2362 argument_unavailable_error("access", "effective_ids");
2363 goto exit;
2364 }
2365#endif
2366
2367#ifdef MS_WINDOWS
2368 Py_BEGIN_ALLOW_THREADS
2369 if (path.wide != NULL)
2370 attr = GetFileAttributesW(path.wide);
2371 else
2372 attr = GetFileAttributesA(path.narrow);
2373 Py_END_ALLOW_THREADS
2374
2375 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002376 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002377 * * we didn't get a -1, and
2378 * * write access wasn't requested,
2379 * * or the file isn't read-only,
2380 * * or it's a directory.
2381 * (Directories cannot be read-only on Windows.)
2382 */
2383 return_value = PyBool_FromLong(
2384 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002385 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002386 !(attr & FILE_ATTRIBUTE_READONLY) ||
2387 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2388#else
2389
2390 Py_BEGIN_ALLOW_THREADS
2391#ifdef HAVE_FACCESSAT
2392 if ((dir_fd != DEFAULT_DIR_FD) ||
2393 effective_ids ||
2394 !follow_symlinks) {
2395 int flags = 0;
2396 if (!follow_symlinks)
2397 flags |= AT_SYMLINK_NOFOLLOW;
2398 if (effective_ids)
2399 flags |= AT_EACCESS;
2400 result = faccessat(dir_fd, path.narrow, mode, flags);
2401 }
2402 else
2403#endif
2404 result = access(path.narrow, mode);
2405 Py_END_ALLOW_THREADS
2406 return_value = PyBool_FromLong(!result);
2407#endif
2408
2409#ifndef HAVE_FACCESSAT
2410exit:
2411#endif
2412 path_cleanup(&path);
2413 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002414}
2415
Guido van Rossumd371ff11999-01-25 16:12:23 +00002416#ifndef F_OK
2417#define F_OK 0
2418#endif
2419#ifndef R_OK
2420#define R_OK 4
2421#endif
2422#ifndef W_OK
2423#define W_OK 2
2424#endif
2425#ifndef X_OK
2426#define X_OK 1
2427#endif
2428
2429#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002430PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002431"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002432Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002433
2434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002435posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002436{
Victor Stinner8c62be82010-05-06 00:08:46 +00002437 int id;
2438 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002439
Victor Stinner8c62be82010-05-06 00:08:46 +00002440 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2441 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002442
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002443#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002444 /* file descriptor 0 only, the default input device (stdin) */
2445 if (id == 0) {
2446 ret = ttyname();
2447 }
2448 else {
2449 ret = NULL;
2450 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002451#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002452 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002453#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002454 if (ret == NULL)
2455 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002456 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002457}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002458#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002459
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002460#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002461PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002462"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002463Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002464
2465static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002466posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002467{
Victor Stinner8c62be82010-05-06 00:08:46 +00002468 char *ret;
2469 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002470
Greg Wardb48bc172000-03-01 21:51:56 +00002471#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002472 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002473#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002474 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002475#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002476 if (ret == NULL)
2477 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002478 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002479}
2480#endif
2481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002482PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002483"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002484Change the current working directory to the specified path.\n\
2485\n\
2486path may always be specified as a string.\n\
2487On some platforms, path may also be specified as an open file descriptor.\n\
2488 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002489
Barry Warsaw53699e91996-12-10 23:23:01 +00002490static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002491posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002492{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002493 path_t path;
2494 int result;
2495 PyObject *return_value = NULL;
2496 static char *keywords[] = {"path", NULL};
2497
2498 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002499 path.function_name = "chdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002500#ifdef HAVE_FCHDIR
2501 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002502#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002503 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2504 path_converter, &path
2505 ))
2506 return NULL;
2507
2508 Py_BEGIN_ALLOW_THREADS
2509#ifdef MS_WINDOWS
2510 if (path.wide)
2511 result = win32_wchdir(path.wide);
2512 else
2513 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002514 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002515#else
2516#ifdef HAVE_FCHDIR
2517 if (path.fd != -1)
2518 result = fchdir(path.fd);
2519 else
2520#endif
2521 result = chdir(path.narrow);
2522#endif
2523 Py_END_ALLOW_THREADS
2524
2525 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002526 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002527 goto exit;
2528 }
2529
2530 return_value = Py_None;
2531 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002532
Larry Hastings9cf065c2012-06-22 16:30:09 -07002533exit:
2534 path_cleanup(&path);
2535 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002536}
2537
Fred Drake4d1e64b2002-04-15 19:40:07 +00002538#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002539PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002540"fchdir(fd)\n\n\
2541Change to the directory of the given file descriptor. fd must be\n\
2542opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002543
2544static PyObject *
2545posix_fchdir(PyObject *self, PyObject *fdobj)
2546{
Victor Stinner8c62be82010-05-06 00:08:46 +00002547 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002548}
2549#endif /* HAVE_FCHDIR */
2550
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002551
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002552PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002553"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2554Change the access permissions of a file.\n\
2555\n\
2556path may always be specified as a string.\n\
2557On some platforms, path may also be specified as an open file descriptor.\n\
2558 If this functionality is unavailable, using it raises an exception.\n\
2559If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2560 and path should be relative; path will then be relative to that directory.\n\
2561If follow_symlinks is False, and the last element of the path is a symbolic\n\
2562 link, chmod will modify the symbolic link itself instead of the file the\n\
2563 link points to.\n\
2564It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2565 an open file descriptor.\n\
2566dir_fd and follow_symlinks may not be implemented on your platform.\n\
2567 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002568
Barry Warsaw53699e91996-12-10 23:23:01 +00002569static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002570posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002571{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572 path_t path;
2573 int mode;
2574 int dir_fd = DEFAULT_DIR_FD;
2575 int follow_symlinks = 1;
2576 int result;
2577 PyObject *return_value = NULL;
2578 static char *keywords[] = {"path", "mode", "dir_fd",
2579 "follow_symlinks", NULL};
2580
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002581#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002582 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002583#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002584
Larry Hastings9cf065c2012-06-22 16:30:09 -07002585#ifdef HAVE_FCHMODAT
2586 int fchmodat_nofollow_unsupported = 0;
2587#endif
2588
2589 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002590 path.function_name = "chmod";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002591#ifdef HAVE_FCHMOD
2592 path.allow_fd = 1;
2593#endif
2594 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2595 path_converter, &path,
2596 &mode,
2597#ifdef HAVE_FCHMODAT
2598 dir_fd_converter, &dir_fd,
2599#else
2600 dir_fd_unavailable, &dir_fd,
2601#endif
2602 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002603 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002604
2605#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2606 if (follow_symlinks_specified("chmod", follow_symlinks))
2607 goto exit;
2608#endif
2609
2610#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002611 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002612 if (path.wide)
2613 attr = GetFileAttributesW(path.wide);
2614 else
2615 attr = GetFileAttributesA(path.narrow);
2616 if (attr == 0xFFFFFFFF)
2617 result = 0;
2618 else {
2619 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002620 attr &= ~FILE_ATTRIBUTE_READONLY;
2621 else
2622 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623 if (path.wide)
2624 result = SetFileAttributesW(path.wide, attr);
2625 else
2626 result = SetFileAttributesA(path.narrow, attr);
2627 }
2628 Py_END_ALLOW_THREADS
2629
2630 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01002631 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002632 goto exit;
2633 }
2634#else /* MS_WINDOWS */
2635 Py_BEGIN_ALLOW_THREADS
2636#ifdef HAVE_FCHMOD
2637 if (path.fd != -1)
2638 result = fchmod(path.fd, mode);
2639 else
2640#endif
2641#ifdef HAVE_LCHMOD
2642 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2643 result = lchmod(path.narrow, mode);
2644 else
2645#endif
2646#ifdef HAVE_FCHMODAT
2647 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2648 /*
2649 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2650 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002651 * and then says it isn't implemented yet.
2652 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002653 *
2654 * Once it is supported, os.chmod will automatically
2655 * support dir_fd and follow_symlinks=False. (Hopefully.)
2656 * Until then, we need to be careful what exception we raise.
2657 */
2658 result = fchmodat(dir_fd, path.narrow, mode,
2659 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2660 /*
2661 * But wait! We can't throw the exception without allowing threads,
2662 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2663 */
2664 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002665 result &&
2666 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2667 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002668 }
2669 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002670#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002671 result = chmod(path.narrow, mode);
2672 Py_END_ALLOW_THREADS
2673
2674 if (result) {
2675#ifdef HAVE_FCHMODAT
2676 if (fchmodat_nofollow_unsupported) {
2677 if (dir_fd != DEFAULT_DIR_FD)
2678 dir_fd_and_follow_symlinks_invalid("chmod",
2679 dir_fd, follow_symlinks);
2680 else
2681 follow_symlinks_specified("chmod", follow_symlinks);
2682 }
2683 else
2684#endif
Victor Stinner292c8352012-10-30 02:17:38 +01002685 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002686 goto exit;
2687 }
2688#endif
2689
2690 Py_INCREF(Py_None);
2691 return_value = Py_None;
2692exit:
2693 path_cleanup(&path);
2694 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002695}
2696
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697
Christian Heimes4e30a842007-11-30 22:12:06 +00002698#ifdef HAVE_FCHMOD
2699PyDoc_STRVAR(posix_fchmod__doc__,
2700"fchmod(fd, mode)\n\n\
2701Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002702descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002703
2704static PyObject *
2705posix_fchmod(PyObject *self, PyObject *args)
2706{
Victor Stinner8c62be82010-05-06 00:08:46 +00002707 int fd, mode, res;
2708 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2709 return NULL;
2710 Py_BEGIN_ALLOW_THREADS
2711 res = fchmod(fd, mode);
2712 Py_END_ALLOW_THREADS
2713 if (res < 0)
2714 return posix_error();
2715 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002716}
2717#endif /* HAVE_FCHMOD */
2718
2719#ifdef HAVE_LCHMOD
2720PyDoc_STRVAR(posix_lchmod__doc__,
2721"lchmod(path, mode)\n\n\
2722Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002723affects the link itself rather than the target.\n\
2724Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002725
2726static PyObject *
2727posix_lchmod(PyObject *self, PyObject *args)
2728{
Victor Stinner292c8352012-10-30 02:17:38 +01002729 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002730 int i;
2731 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002732 memset(&path, 0, sizeof(path));
2733 path.function_name = "lchmod";
2734 if (!PyArg_ParseTuple(args, "O&i:lchmod",
2735 path_converter, &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002736 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002737 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002738 res = lchmod(path.narrow, i);
Victor Stinner8c62be82010-05-06 00:08:46 +00002739 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002740 if (res < 0) {
2741 path_error(&path);
2742 path_cleanup(&path);
2743 return NULL;
2744 }
2745 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002746 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002747}
2748#endif /* HAVE_LCHMOD */
2749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002750
Thomas Wouterscf297e42007-02-23 15:07:44 +00002751#ifdef HAVE_CHFLAGS
2752PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002753"chflags(path, flags, *, follow_symlinks=True)\n\n\
2754Set file flags.\n\
2755\n\
2756If follow_symlinks is False, and the last element of the path is a symbolic\n\
2757 link, chflags will change flags on the symbolic link itself instead of the\n\
2758 file the link points to.\n\
2759follow_symlinks may not be implemented on your platform. If it is\n\
2760unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002761
2762static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002763posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002764{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002765 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002766 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002767 int follow_symlinks = 1;
2768 int result;
2769 PyObject *return_value;
2770 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2771
2772 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002773 path.function_name = "chflags";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002774 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2775 path_converter, &path,
2776 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002777 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002778
2779#ifndef HAVE_LCHFLAGS
2780 if (follow_symlinks_specified("chflags", follow_symlinks))
2781 goto exit;
2782#endif
2783
Victor Stinner8c62be82010-05-06 00:08:46 +00002784 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002785#ifdef HAVE_LCHFLAGS
2786 if (!follow_symlinks)
2787 result = lchflags(path.narrow, flags);
2788 else
2789#endif
2790 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002791 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002792
2793 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002794 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795 goto exit;
2796 }
2797
2798 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002799 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800
2801exit:
2802 path_cleanup(&path);
2803 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002804}
2805#endif /* HAVE_CHFLAGS */
2806
2807#ifdef HAVE_LCHFLAGS
2808PyDoc_STRVAR(posix_lchflags__doc__,
2809"lchflags(path, flags)\n\n\
2810Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811This function will not follow symbolic links.\n\
2812Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002813
2814static PyObject *
2815posix_lchflags(PyObject *self, PyObject *args)
2816{
Victor Stinner292c8352012-10-30 02:17:38 +01002817 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002818 unsigned long flags;
2819 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01002820 memset(&path, 0, sizeof(path));
2821 path.function_name = "lchflags";
Victor Stinner8c62be82010-05-06 00:08:46 +00002822 if (!PyArg_ParseTuple(args, "O&k:lchflags",
Victor Stinner292c8352012-10-30 02:17:38 +01002823 path_converter, &path, &flags))
Victor Stinner8c62be82010-05-06 00:08:46 +00002824 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002825 Py_BEGIN_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002826 res = lchflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002827 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002828 if (res < 0) {
2829 path_error(&path);
2830 path_cleanup(&path);
2831 return NULL;
2832 }
2833 path_cleanup(&path);
2834 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002835}
2836#endif /* HAVE_LCHFLAGS */
2837
Martin v. Löwis244edc82001-10-04 22:44:26 +00002838#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002840"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002841Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002842
2843static PyObject *
2844posix_chroot(PyObject *self, PyObject *args)
2845{
Victor Stinner292c8352012-10-30 02:17:38 +01002846 return posix_1str("chroot", args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002847}
2848#endif
2849
Guido van Rossum21142a01999-01-08 21:05:37 +00002850#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002851PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002852"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002853force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002854
2855static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002856posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002857{
Stefan Krah0e803b32010-11-26 16:16:47 +00002858 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002859}
2860#endif /* HAVE_FSYNC */
2861
Ross Lagerwall7807c352011-03-17 20:20:30 +02002862#ifdef HAVE_SYNC
2863PyDoc_STRVAR(posix_sync__doc__,
2864"sync()\n\n\
2865Force write of everything to disk.");
2866
2867static PyObject *
2868posix_sync(PyObject *self, PyObject *noargs)
2869{
2870 Py_BEGIN_ALLOW_THREADS
2871 sync();
2872 Py_END_ALLOW_THREADS
2873 Py_RETURN_NONE;
2874}
2875#endif
2876
Guido van Rossum21142a01999-01-08 21:05:37 +00002877#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002878
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002879#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002880extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2881#endif
2882
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002883PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002884"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002885force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002886 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002887
2888static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002889posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002890{
Stefan Krah0e803b32010-11-26 16:16:47 +00002891 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002892}
2893#endif /* HAVE_FDATASYNC */
2894
2895
Fredrik Lundh10723342000-07-10 16:38:09 +00002896#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002897PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002898"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2899Change the owner and group id of path to the numeric uid and gid.\n\
2900\n\
2901path may always be specified as a string.\n\
2902On some platforms, path may also be specified as an open file descriptor.\n\
2903 If this functionality is unavailable, using it raises an exception.\n\
2904If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2905 and path should be relative; path will then be relative to that directory.\n\
2906If follow_symlinks is False, and the last element of the path is a symbolic\n\
2907 link, chown will modify the symbolic link itself instead of the file the\n\
2908 link points to.\n\
2909It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2910 an open file descriptor.\n\
2911dir_fd and follow_symlinks may not be implemented on your platform.\n\
2912 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002913
Barry Warsaw53699e91996-12-10 23:23:01 +00002914static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002915posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002916{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002917 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002918 uid_t uid;
2919 gid_t gid;
2920 int dir_fd = DEFAULT_DIR_FD;
2921 int follow_symlinks = 1;
2922 int result;
2923 PyObject *return_value = NULL;
2924 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2925 "follow_symlinks", NULL};
2926
2927 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01002928 path.function_name = "chown";
Larry Hastings9cf065c2012-06-22 16:30:09 -07002929#ifdef HAVE_FCHOWN
2930 path.allow_fd = 1;
2931#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002932 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002933 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002934 _Py_Uid_Converter, &uid,
2935 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002936#ifdef HAVE_FCHOWNAT
2937 dir_fd_converter, &dir_fd,
2938#else
2939 dir_fd_unavailable, &dir_fd,
2940#endif
2941 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002942 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002943
2944#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2945 if (follow_symlinks_specified("chown", follow_symlinks))
2946 goto exit;
2947#endif
2948 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2949 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2950 goto exit;
2951
2952#ifdef __APPLE__
2953 /*
2954 * This is for Mac OS X 10.3, which doesn't have lchown.
2955 * (But we still have an lchown symbol because of weak-linking.)
2956 * It doesn't have fchownat either. So there's no possibility
2957 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02002958 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002959 if ((!follow_symlinks) && (lchown == NULL)) {
2960 follow_symlinks_specified("chown", follow_symlinks);
2961 goto exit;
2962 }
2963#endif
2964
Victor Stinner8c62be82010-05-06 00:08:46 +00002965 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002966#ifdef HAVE_FCHOWN
2967 if (path.fd != -1)
2968 result = fchown(path.fd, uid, gid);
2969 else
2970#endif
2971#ifdef HAVE_LCHOWN
2972 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2973 result = lchown(path.narrow, uid, gid);
2974 else
2975#endif
2976#ifdef HAVE_FCHOWNAT
2977 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
2978 result = fchownat(dir_fd, path.narrow, uid, gid,
2979 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2980 else
2981#endif
2982 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984
2985 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01002986 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002987 goto exit;
2988 }
2989
2990 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002991 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002992
2993exit:
2994 path_cleanup(&path);
2995 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002996}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002997#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002998
Christian Heimes4e30a842007-11-30 22:12:06 +00002999#ifdef HAVE_FCHOWN
3000PyDoc_STRVAR(posix_fchown__doc__,
3001"fchown(fd, uid, gid)\n\n\
3002Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003004
3005static PyObject *
3006posix_fchown(PyObject *self, PyObject *args)
3007{
Victor Stinner8c62be82010-05-06 00:08:46 +00003008 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003009 uid_t uid;
3010 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003011 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003012 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3013 _Py_Uid_Converter, &uid,
3014 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003015 return NULL;
3016 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003017 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 Py_END_ALLOW_THREADS
3019 if (res < 0)
3020 return posix_error();
3021 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003022}
3023#endif /* HAVE_FCHOWN */
3024
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003025#ifdef HAVE_LCHOWN
3026PyDoc_STRVAR(posix_lchown__doc__,
3027"lchown(path, uid, gid)\n\n\
3028Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003029This function will not follow symbolic links.\n\
3030Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003031
3032static PyObject *
3033posix_lchown(PyObject *self, PyObject *args)
3034{
Victor Stinner292c8352012-10-30 02:17:38 +01003035 path_t path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003036 uid_t uid;
3037 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003038 int res;
Victor Stinner292c8352012-10-30 02:17:38 +01003039 memset(&path, 0, sizeof(path));
3040 path.function_name = "lchown";
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003041 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner292c8352012-10-30 02:17:38 +01003042 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003043 _Py_Uid_Converter, &uid,
3044 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003045 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003046 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakac2d02002013-02-10 22:03:08 +02003047 res = lchown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003048 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003049 if (res < 0) {
3050 path_error(&path);
3051 path_cleanup(&path);
3052 return NULL;
3053 }
3054 path_cleanup(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003055 Py_INCREF(Py_None);
3056 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003057}
3058#endif /* HAVE_LCHOWN */
3059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003060
Guido van Rossum36bc6801995-06-14 22:54:23 +00003061#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003062static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003063posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003064{
Victor Stinner8c62be82010-05-06 00:08:46 +00003065 char buf[1026];
3066 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003067
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003068#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003069 if (!use_bytes) {
3070 wchar_t wbuf[1026];
3071 wchar_t *wbuf2 = wbuf;
3072 PyObject *resobj;
3073 DWORD len;
3074 Py_BEGIN_ALLOW_THREADS
3075 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3076 /* If the buffer is large enough, len does not include the
3077 terminating \0. If the buffer is too small, len includes
3078 the space needed for the terminator. */
3079 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3080 wbuf2 = malloc(len * sizeof(wchar_t));
3081 if (wbuf2)
3082 len = GetCurrentDirectoryW(len, wbuf2);
3083 }
3084 Py_END_ALLOW_THREADS
3085 if (!wbuf2) {
3086 PyErr_NoMemory();
3087 return NULL;
3088 }
3089 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003090 if (wbuf2 != wbuf)
3091 free(wbuf2);
3092 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 }
3094 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003095 if (wbuf2 != wbuf)
3096 free(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003097 return resobj;
3098 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003099
3100 if (win32_warn_bytes_api())
3101 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003102#endif
3103
Victor Stinner8c62be82010-05-06 00:08:46 +00003104 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003105 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003106 Py_END_ALLOW_THREADS
3107 if (res == NULL)
3108 return posix_error();
3109 if (use_bytes)
3110 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003111 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003112}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003113
3114PyDoc_STRVAR(posix_getcwd__doc__,
3115"getcwd() -> path\n\n\
3116Return a unicode string representing the current working directory.");
3117
3118static PyObject *
3119posix_getcwd_unicode(PyObject *self)
3120{
3121 return posix_getcwd(0);
3122}
3123
3124PyDoc_STRVAR(posix_getcwdb__doc__,
3125"getcwdb() -> path\n\n\
3126Return a bytes string representing the current working directory.");
3127
3128static PyObject *
3129posix_getcwd_bytes(PyObject *self)
3130{
3131 return posix_getcwd(1);
3132}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003133#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003134
Larry Hastings9cf065c2012-06-22 16:30:09 -07003135#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3136#define HAVE_LINK 1
3137#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003138
Guido van Rossumb6775db1994-08-01 11:34:53 +00003139#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003140PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003141"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3142Create a hard link to a file.\n\
3143\n\
3144If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3145 descriptor open to a directory, and the respective path string (src or dst)\n\
3146 should be relative; the path will then be relative to that directory.\n\
3147If follow_symlinks is False, and the last element of src is a symbolic\n\
3148 link, link will create a link to the symbolic link itself instead of the\n\
3149 file the link points to.\n\
3150src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3151 platform. If they are unavailable, using them will raise a\n\
3152 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003153
Barry Warsaw53699e91996-12-10 23:23:01 +00003154static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003155posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003156{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157 path_t src, dst;
3158 int src_dir_fd = DEFAULT_DIR_FD;
3159 int dst_dir_fd = DEFAULT_DIR_FD;
3160 int follow_symlinks = 1;
3161 PyObject *return_value = NULL;
3162 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3163 "follow_symlinks", NULL};
3164#ifdef MS_WINDOWS
3165 BOOL result;
3166#else
3167 int result;
3168#endif
3169
3170 memset(&src, 0, sizeof(src));
3171 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003172 src.function_name = "link";
3173 dst.function_name = "link";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3175 path_converter, &src,
3176 path_converter, &dst,
3177 dir_fd_converter, &src_dir_fd,
3178 dir_fd_converter, &dst_dir_fd,
3179 &follow_symlinks))
3180 return NULL;
3181
3182#ifndef HAVE_LINKAT
3183 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3184 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3185 goto exit;
3186 }
3187#endif
3188
3189 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3190 PyErr_SetString(PyExc_NotImplementedError,
3191 "link: src and dst must be the same type");
3192 goto exit;
3193 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003194
Brian Curtin1b9df392010-11-24 20:24:31 +00003195#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003196 Py_BEGIN_ALLOW_THREADS
3197 if (src.wide)
3198 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3199 else
3200 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3201 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003202
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003204 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003205 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003206 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003207#else
3208 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003209#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003210 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3211 (dst_dir_fd != DEFAULT_DIR_FD) ||
3212 (!follow_symlinks))
3213 result = linkat(src_dir_fd, src.narrow,
3214 dst_dir_fd, dst.narrow,
3215 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3216 else
3217#endif
3218 result = link(src.narrow, dst.narrow);
3219 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003220
Larry Hastings9cf065c2012-06-22 16:30:09 -07003221 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003222 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003223 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003224 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003225#endif
3226
3227 return_value = Py_None;
3228 Py_INCREF(Py_None);
3229
3230exit:
3231 path_cleanup(&src);
3232 path_cleanup(&dst);
3233 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003234}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003235#endif
3236
Brian Curtin1b9df392010-11-24 20:24:31 +00003237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003238
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003239PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003240"listdir(path='.') -> list_of_filenames\n\n\
3241Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003242The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003243entries '.' and '..' even if they are present in the directory.\n\
3244\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003245path can be specified as either str or bytes. If path is bytes,\n\
3246 the filenames returned will also be bytes; in all other circumstances\n\
3247 the filenames returned will be str.\n\
3248On some platforms, path may also be specified as an open file descriptor;\n\
3249 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003250 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003251
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003252#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003253static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003254_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003255{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003256 static char *keywords[] = {"path", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07003257 PyObject *v;
3258 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3259 BOOL result;
3260 WIN32_FIND_DATA FileData;
3261 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3262 char *bufptr = namebuf;
3263 /* only claim to have space for MAX_PATH */
3264 Py_ssize_t len = sizeof(namebuf)-5;
3265 PyObject *po = NULL;
3266 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003267
Gregory P. Smith40a21602013-03-20 20:52:50 -07003268 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003269 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003270 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003271
Gregory P. Smith40a21602013-03-20 20:52:50 -07003272 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003273 po_wchars = L".";
3274 len = 1;
3275 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003276 po_wchars = path->wide;
3277 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003278 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003279 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3281 if (!wnamebuf) {
3282 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003283 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003285 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003287 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003288 if (wch != L'/' && wch != L'\\' && wch != L':')
3289 wnamebuf[len++] = L'\\';
3290 wcscpy(wnamebuf + len, L"*.*");
3291 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003292 if ((list = PyList_New(0)) == NULL) {
3293 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003295 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003296 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003297 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003298 if (hFindFile == INVALID_HANDLE_VALUE) {
3299 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003300 if (error == ERROR_FILE_NOT_FOUND)
3301 goto exit;
3302 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003303 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003304 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003305 }
3306 do {
3307 /* Skip over . and .. */
3308 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3309 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003310 v = PyUnicode_FromWideChar(wFileData.cFileName,
3311 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003312 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003313 Py_DECREF(list);
3314 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003315 break;
3316 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003317 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003318 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003319 Py_DECREF(list);
3320 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003321 break;
3322 }
3323 Py_DECREF(v);
3324 }
3325 Py_BEGIN_ALLOW_THREADS
3326 result = FindNextFileW(hFindFile, &wFileData);
3327 Py_END_ALLOW_THREADS
3328 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3329 it got to the end of the directory. */
3330 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003331 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003332 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003334 }
3335 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003336
Larry Hastings9cf065c2012-06-22 16:30:09 -07003337 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003338 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003339 strcpy(namebuf, path->narrow);
3340 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003341 if (len > 0) {
3342 char ch = namebuf[len-1];
3343 if (ch != SEP && ch != ALTSEP && ch != ':')
3344 namebuf[len++] = '/';
3345 strcpy(namebuf + len, "*.*");
3346 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003347
Larry Hastings9cf065c2012-06-22 16:30:09 -07003348 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003349 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003350
Antoine Pitroub73caab2010-08-09 23:39:31 +00003351 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003352 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003353 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 if (hFindFile == INVALID_HANDLE_VALUE) {
3355 int error = GetLastError();
3356 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003357 goto exit;
3358 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003359 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003360 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003361 }
3362 do {
3363 /* Skip over . and .. */
3364 if (strcmp(FileData.cFileName, ".") != 0 &&
3365 strcmp(FileData.cFileName, "..") != 0) {
3366 v = PyBytes_FromString(FileData.cFileName);
3367 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368 Py_DECREF(list);
3369 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 break;
3371 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003372 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003373 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003374 Py_DECREF(list);
3375 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003376 break;
3377 }
3378 Py_DECREF(v);
3379 }
3380 Py_BEGIN_ALLOW_THREADS
3381 result = FindNextFile(hFindFile, &FileData);
3382 Py_END_ALLOW_THREADS
3383 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3384 it got to the end of the directory. */
3385 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003387 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003389 }
3390 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003391
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392exit:
3393 if (hFindFile != INVALID_HANDLE_VALUE) {
3394 if (FindClose(hFindFile) == FALSE) {
3395 if (list != NULL) {
3396 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003397 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398 }
3399 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003400 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003401 if (wnamebuf)
3402 free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003403
Larry Hastings9cf065c2012-06-22 16:30:09 -07003404 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003405} /* end of _listdir_windows_no_opendir */
3406
3407#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3408
3409static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003410_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003411{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003412 int fd = -1;
3413
3414 PyObject *v;
3415 DIR *dirp = NULL;
3416 struct dirent *ep;
3417 int return_str; /* if false, return bytes */
3418
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003421 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003423 Py_BEGIN_ALLOW_THREADS
Gregory P. Smith40a21602013-03-20 20:52:50 -07003424 fd = dup(path->fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003425 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426
3427 if (fd == -1) {
3428 list = posix_error();
3429 goto exit;
3430 }
3431
Larry Hastingsfdaea062012-06-25 04:42:23 -07003432 return_str = 1;
3433
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 Py_BEGIN_ALLOW_THREADS
3435 dirp = fdopendir(fd);
3436 Py_END_ALLOW_THREADS
3437 }
3438 else
3439#endif
3440 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003441 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003442 if (path->narrow) {
3443 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003444 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003445 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003446 }
3447 else {
3448 name = ".";
3449 return_str = 1;
3450 }
3451
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452 Py_BEGIN_ALLOW_THREADS
3453 dirp = opendir(name);
3454 Py_END_ALLOW_THREADS
3455 }
3456
3457 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003458 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003459 goto exit;
3460 }
3461 if ((list = PyList_New(0)) == NULL) {
3462 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 }
3464 for (;;) {
3465 errno = 0;
3466 Py_BEGIN_ALLOW_THREADS
3467 ep = readdir(dirp);
3468 Py_END_ALLOW_THREADS
3469 if (ep == NULL) {
3470 if (errno == 0) {
3471 break;
3472 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003473 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003474 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003476 }
3477 }
3478 if (ep->d_name[0] == '.' &&
3479 (NAMLEN(ep) == 1 ||
3480 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3481 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003482 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003483 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3484 else
3485 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 break;
3489 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003492 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003493 break;
3494 }
3495 Py_DECREF(v);
3496 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003497
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498exit:
3499 if (dirp != NULL) {
3500 Py_BEGIN_ALLOW_THREADS
3501 if (fd > -1)
3502 rewinddir(dirp);
3503 closedir(dirp);
3504 Py_END_ALLOW_THREADS
3505 }
3506
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003508} /* end of _posix_listdir */
3509#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003510
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003511static PyObject *
3512posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
3513{
Gregory P. Smith40a21602013-03-20 20:52:50 -07003514 path_t path;
3515 PyObject *list = NULL;
3516 static char *keywords[] = {"path", NULL};
3517 PyObject *return_value;
3518
3519 memset(&path, 0, sizeof(path));
3520 path.function_name = "listdir";
3521 path.nullable = 1;
3522#ifdef HAVE_FDOPENDIR
3523 path.allow_fd = 1;
3524 path.fd = -1;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003525#endif
Gregory P. Smith40a21602013-03-20 20:52:50 -07003526
3527 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3528 path_converter, &path)) {
3529 return NULL;
3530 }
3531
3532#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3533 return_value = _listdir_windows_no_opendir(&path, list);
3534#else
3535 return_value = _posix_listdir(&path, list);
3536#endif
3537 path_cleanup(&path);
3538 return return_value;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003539}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003540
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003541#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003542/* A helper function for abspath on win32 */
3543static PyObject *
3544posix__getfullpathname(PyObject *self, PyObject *args)
3545{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003546 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 char outbuf[MAX_PATH*2];
3548 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003549 PyObject *po;
3550
3551 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3552 {
3553 wchar_t *wpath;
3554 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3555 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 DWORD result;
3557 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003558
3559 wpath = PyUnicode_AsUnicode(po);
3560 if (wpath == NULL)
3561 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003563 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003565 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003566 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 if (!woutbufp)
3568 return PyErr_NoMemory();
3569 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3570 }
3571 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003572 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003573 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003574 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003575 if (woutbufp != woutbuf)
3576 free(woutbufp);
3577 return v;
3578 }
3579 /* Drop the argument parsing error as narrow strings
3580 are also valid. */
3581 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003582
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003583 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3584 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003586 if (win32_warn_bytes_api())
3587 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003588 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 outbuf, &temp)) {
3590 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003591 return NULL;
3592 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3594 return PyUnicode_Decode(outbuf, strlen(outbuf),
3595 Py_FileSystemDefaultEncoding, NULL);
3596 }
3597 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003598} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003599
Brian Curtind25aef52011-06-13 15:16:04 -05003600
Brian Curtinf5e76d02010-11-24 13:14:05 +00003601
Brian Curtind40e6f72010-07-08 21:39:08 +00003602/* A helper function for samepath on windows */
3603static PyObject *
3604posix__getfinalpathname(PyObject *self, PyObject *args)
3605{
3606 HANDLE hFile;
3607 int buf_size;
3608 wchar_t *target_path;
3609 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003610 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003611 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003612
Victor Stinnereb5657a2011-09-30 01:44:27 +02003613 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003614 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003615 path = PyUnicode_AsUnicode(po);
3616 if (path == NULL)
3617 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003618
3619 if(!check_GetFinalPathNameByHandle()) {
3620 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3621 NotImplementedError. */
3622 return PyErr_Format(PyExc_NotImplementedError,
3623 "GetFinalPathNameByHandle not available on this platform");
3624 }
3625
3626 hFile = CreateFileW(
3627 path,
3628 0, /* desired access */
3629 0, /* share mode */
3630 NULL, /* security attributes */
3631 OPEN_EXISTING,
3632 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3633 FILE_FLAG_BACKUP_SEMANTICS,
3634 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003635
Victor Stinnereb5657a2011-09-30 01:44:27 +02003636 if(hFile == INVALID_HANDLE_VALUE)
3637 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003638
3639 /* We have a good handle to the target, use it to determine the
3640 target path name. */
3641 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3642
3643 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003644 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003645
3646 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3647 if(!target_path)
3648 return PyErr_NoMemory();
3649
3650 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3651 buf_size, VOLUME_NAME_DOS);
3652 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003653 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003654
3655 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003656 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003657
3658 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003659 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003660 free(target_path);
3661 return result;
3662
3663} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003664
Brian Curtin95d028f2011-06-09 09:10:38 -05003665PyDoc_STRVAR(posix__isdir__doc__,
3666"Return true if the pathname refers to an existing directory.");
3667
Brian Curtin9c669cc2011-06-08 18:17:18 -05003668static PyObject *
3669posix__isdir(PyObject *self, PyObject *args)
3670{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003671 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003672 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003673 DWORD attributes;
3674
3675 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003676 wchar_t *wpath = PyUnicode_AsUnicode(po);
3677 if (wpath == NULL)
3678 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003679
3680 attributes = GetFileAttributesW(wpath);
3681 if (attributes == INVALID_FILE_ATTRIBUTES)
3682 Py_RETURN_FALSE;
3683 goto check;
3684 }
3685 /* Drop the argument parsing error as narrow strings
3686 are also valid. */
3687 PyErr_Clear();
3688
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003689 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003690 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003691 if (win32_warn_bytes_api())
3692 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003693 attributes = GetFileAttributesA(path);
3694 if (attributes == INVALID_FILE_ATTRIBUTES)
3695 Py_RETURN_FALSE;
3696
3697check:
3698 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3699 Py_RETURN_TRUE;
3700 else
3701 Py_RETURN_FALSE;
3702}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003703#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003704
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003705PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3707Create a directory.\n\
3708\n\
3709If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3710 and path should be relative; path will then be relative to that directory.\n\
3711dir_fd may not be implemented on your platform.\n\
3712 If it is unavailable, using it will raise a NotImplementedError.\n\
3713\n\
3714The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003715
Barry Warsaw53699e91996-12-10 23:23:01 +00003716static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003717posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003718{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003719 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003720 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003721 int dir_fd = DEFAULT_DIR_FD;
3722 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3723 PyObject *return_value = NULL;
3724 int result;
3725
3726 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003727 path.function_name = "mkdir";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3729 path_converter, &path, &mode,
3730#ifdef HAVE_MKDIRAT
3731 dir_fd_converter, &dir_fd
3732#else
3733 dir_fd_unavailable, &dir_fd
3734#endif
3735 ))
3736 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003737
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003738#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003739 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003740 if (path.wide)
3741 result = CreateDirectoryW(path.wide, NULL);
3742 else
3743 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003744 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003745
Larry Hastings9cf065c2012-06-22 16:30:09 -07003746 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003747 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003748 goto exit;
3749 }
3750#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003751 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003752#if HAVE_MKDIRAT
3753 if (dir_fd != DEFAULT_DIR_FD)
3754 result = mkdirat(dir_fd, path.narrow, mode);
3755 else
3756#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003757#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003758 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003759#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003760 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003761#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003762 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003763 if (result < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01003764 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003765 goto exit;
3766 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003767#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003768 return_value = Py_None;
3769 Py_INCREF(Py_None);
3770exit:
3771 path_cleanup(&path);
3772 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003773}
3774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003775
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003776/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3777#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003778#include <sys/resource.h>
3779#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003780
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003781
3782#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003783PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003784"nice(inc) -> new_priority\n\n\
3785Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003786
Barry Warsaw53699e91996-12-10 23:23:01 +00003787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003788posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003789{
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003791
Victor Stinner8c62be82010-05-06 00:08:46 +00003792 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3793 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003794
Victor Stinner8c62be82010-05-06 00:08:46 +00003795 /* There are two flavours of 'nice': one that returns the new
3796 priority (as required by almost all standards out there) and the
3797 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3798 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003799
Victor Stinner8c62be82010-05-06 00:08:46 +00003800 If we are of the nice family that returns the new priority, we
3801 need to clear errno before the call, and check if errno is filled
3802 before calling posix_error() on a returnvalue of -1, because the
3803 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003804
Victor Stinner8c62be82010-05-06 00:08:46 +00003805 errno = 0;
3806 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003807#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003808 if (value == 0)
3809 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003810#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003811 if (value == -1 && errno != 0)
3812 /* either nice() or getpriority() returned an error */
3813 return posix_error();
3814 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003815}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003816#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003817
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003818
3819#ifdef HAVE_GETPRIORITY
3820PyDoc_STRVAR(posix_getpriority__doc__,
3821"getpriority(which, who) -> current_priority\n\n\
3822Get program scheduling priority.");
3823
3824static PyObject *
3825posix_getpriority(PyObject *self, PyObject *args)
3826{
3827 int which, who, retval;
3828
3829 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3830 return NULL;
3831 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003832 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003833 if (errno != 0)
3834 return posix_error();
3835 return PyLong_FromLong((long)retval);
3836}
3837#endif /* HAVE_GETPRIORITY */
3838
3839
3840#ifdef HAVE_SETPRIORITY
3841PyDoc_STRVAR(posix_setpriority__doc__,
3842"setpriority(which, who, prio) -> None\n\n\
3843Set program scheduling priority.");
3844
3845static PyObject *
3846posix_setpriority(PyObject *self, PyObject *args)
3847{
3848 int which, who, prio, retval;
3849
3850 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3851 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003852 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003853 if (retval == -1)
3854 return posix_error();
3855 Py_RETURN_NONE;
3856}
3857#endif /* HAVE_SETPRIORITY */
3858
3859
Barry Warsaw53699e91996-12-10 23:23:01 +00003860static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003861internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003862{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003863 char *function_name = is_replace ? "replace" : "rename";
3864 path_t src;
3865 path_t dst;
3866 int src_dir_fd = DEFAULT_DIR_FD;
3867 int dst_dir_fd = DEFAULT_DIR_FD;
3868 int dir_fd_specified;
3869 PyObject *return_value = NULL;
3870 char format[24];
3871 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3872
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003873#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003875 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003876#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003877 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003878#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003879
3880 memset(&src, 0, sizeof(src));
3881 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01003882 src.function_name = function_name;
3883 dst.function_name = function_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003884 strcpy(format, "O&O&|$O&O&:");
3885 strcat(format, function_name);
3886 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
3887 path_converter, &src,
3888 path_converter, &dst,
3889 dir_fd_converter, &src_dir_fd,
3890 dir_fd_converter, &dst_dir_fd))
3891 return NULL;
3892
3893 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3894 (dst_dir_fd != DEFAULT_DIR_FD);
3895#ifndef HAVE_RENAMEAT
3896 if (dir_fd_specified) {
3897 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
3898 goto exit;
3899 }
3900#endif
3901
3902 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3903 PyErr_Format(PyExc_ValueError,
3904 "%s: src and dst must be the same type", function_name);
3905 goto exit;
3906 }
3907
3908#ifdef MS_WINDOWS
3909 Py_BEGIN_ALLOW_THREADS
3910 if (src.wide)
3911 result = MoveFileExW(src.wide, dst.wide, flags);
3912 else
3913 result = MoveFileExA(src.narrow, dst.narrow, flags);
3914 Py_END_ALLOW_THREADS
3915
3916 if (!result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01003917 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003918 goto exit;
3919 }
3920
3921#else
3922 Py_BEGIN_ALLOW_THREADS
3923#ifdef HAVE_RENAMEAT
3924 if (dir_fd_specified)
3925 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
3926 else
3927#endif
3928 result = rename(src.narrow, dst.narrow);
3929 Py_END_ALLOW_THREADS
3930
3931 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01003932 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003933 goto exit;
3934 }
3935#endif
3936
3937 Py_INCREF(Py_None);
3938 return_value = Py_None;
3939exit:
3940 path_cleanup(&src);
3941 path_cleanup(&dst);
3942 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003943}
3944
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003945PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003946"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3947Rename a file or directory.\n\
3948\n\
3949If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3950 descriptor open to a directory, and the respective path string (src or dst)\n\
3951 should be relative; the path will then be relative to that directory.\n\
3952src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3953 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003954
3955static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003956posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003957{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003958 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003959}
3960
3961PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003962"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
3963Rename a file or directory, overwriting the destination.\n\
3964\n\
3965If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3966 descriptor open to a directory, and the respective path string (src or dst)\n\
3967 should be relative; the path will then be relative to that directory.\n\
3968src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
3969 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003970
3971static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003972posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003973{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003975}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003976
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003977PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003978"rmdir(path, *, dir_fd=None)\n\n\
3979Remove a directory.\n\
3980\n\
3981If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3982 and path should be relative; path will then be relative to that directory.\n\
3983dir_fd may not be implemented on your platform.\n\
3984 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003985
Barry Warsaw53699e91996-12-10 23:23:01 +00003986static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003987posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003988{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003989 path_t path;
3990 int dir_fd = DEFAULT_DIR_FD;
3991 static char *keywords[] = {"path", "dir_fd", NULL};
3992 int result;
3993 PyObject *return_value = NULL;
3994
3995 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01003996 path.function_name = "rmdir";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07003997 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
3998 path_converter, &path,
3999#ifdef HAVE_UNLINKAT
4000 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004001#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004002 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004003#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004004 ))
4005 return NULL;
4006
4007 Py_BEGIN_ALLOW_THREADS
4008#ifdef MS_WINDOWS
4009 if (path.wide)
4010 result = RemoveDirectoryW(path.wide);
4011 else
4012 result = RemoveDirectoryA(path.narrow);
4013 result = !result; /* Windows, success=1, UNIX, success=0 */
4014#else
4015#ifdef HAVE_UNLINKAT
4016 if (dir_fd != DEFAULT_DIR_FD)
4017 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4018 else
4019#endif
4020 result = rmdir(path.narrow);
4021#endif
4022 Py_END_ALLOW_THREADS
4023
4024 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004025 return_value = path_error(&path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004026 goto exit;
4027 }
4028
4029 return_value = Py_None;
4030 Py_INCREF(Py_None);
4031
4032exit:
4033 path_cleanup(&path);
4034 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004035}
4036
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004037
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004038#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004039PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004040"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004041Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004042
Barry Warsaw53699e91996-12-10 23:23:01 +00004043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004044posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004045{
Victor Stinner8c62be82010-05-06 00:08:46 +00004046 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004047#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004048 wchar_t *command;
4049 if (!PyArg_ParseTuple(args, "u:system", &command))
4050 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004051
Victor Stinner8c62be82010-05-06 00:08:46 +00004052 Py_BEGIN_ALLOW_THREADS
4053 sts = _wsystem(command);
4054 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004055#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004056 PyObject *command_obj;
4057 char *command;
4058 if (!PyArg_ParseTuple(args, "O&:system",
4059 PyUnicode_FSConverter, &command_obj))
4060 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004061
Victor Stinner8c62be82010-05-06 00:08:46 +00004062 command = PyBytes_AsString(command_obj);
4063 Py_BEGIN_ALLOW_THREADS
4064 sts = system(command);
4065 Py_END_ALLOW_THREADS
4066 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004067#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004069}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004070#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004071
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004072
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004073PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004074"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004075Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004076
Barry Warsaw53699e91996-12-10 23:23:01 +00004077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004078posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004079{
Victor Stinner8c62be82010-05-06 00:08:46 +00004080 int i;
4081 if (!PyArg_ParseTuple(args, "i:umask", &i))
4082 return NULL;
4083 i = (int)umask(i);
4084 if (i < 0)
4085 return posix_error();
4086 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004087}
4088
Brian Curtind40e6f72010-07-08 21:39:08 +00004089#ifdef MS_WINDOWS
4090
4091/* override the default DeleteFileW behavior so that directory
4092symlinks can be removed with this function, the same as with
4093Unix symlinks */
4094BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4095{
4096 WIN32_FILE_ATTRIBUTE_DATA info;
4097 WIN32_FIND_DATAW find_data;
4098 HANDLE find_data_handle;
4099 int is_directory = 0;
4100 int is_link = 0;
4101
4102 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4103 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004104
Brian Curtind40e6f72010-07-08 21:39:08 +00004105 /* Get WIN32_FIND_DATA structure for the path to determine if
4106 it is a symlink */
4107 if(is_directory &&
4108 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4109 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4110
4111 if(find_data_handle != INVALID_HANDLE_VALUE) {
4112 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4113 FindClose(find_data_handle);
4114 }
4115 }
4116 }
4117
4118 if (is_directory && is_link)
4119 return RemoveDirectoryW(lpFileName);
4120
4121 return DeleteFileW(lpFileName);
4122}
4123#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004125PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004126"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127Remove a file (same as remove()).\n\
4128\n\
4129If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4130 and path should be relative; path will then be relative to that directory.\n\
4131dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004132 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004133
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004134PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004135"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136Remove a file (same as unlink()).\n\
4137\n\
4138If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4139 and path should be relative; path will then be relative to that directory.\n\
4140dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004141 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004142
Barry Warsaw53699e91996-12-10 23:23:01 +00004143static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004144posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004145{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004146 path_t path;
4147 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004148 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004149 int result;
4150 PyObject *return_value = NULL;
4151
4152 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004153 path.function_name = "unlink";
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004154 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155 path_converter, &path,
4156#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004157 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004158#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004159 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004160#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004161 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004162 return NULL;
4163
4164 Py_BEGIN_ALLOW_THREADS
4165#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004166 if (path.wide)
4167 result = Py_DeleteFileW(path.wide);
4168 else
4169 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004170 result = !result; /* Windows, success=1, UNIX, success=0 */
4171#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004172#ifdef HAVE_UNLINKAT
4173 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004174 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004175 else
4176#endif /* HAVE_UNLINKAT */
4177 result = unlink(path.narrow);
4178#endif
4179 Py_END_ALLOW_THREADS
4180
4181 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01004182 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004183 goto exit;
4184 }
4185
4186 return_value = Py_None;
4187 Py_INCREF(Py_None);
4188
4189exit:
4190 path_cleanup(&path);
4191 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004192}
4193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004195PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004196"uname() -> uname_result\n\n\
4197Return an object identifying the current operating system.\n\
4198The object behaves like a named tuple with the following fields:\n\
4199 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004200
Larry Hastings605a62d2012-06-24 04:33:36 -07004201static PyStructSequence_Field uname_result_fields[] = {
4202 {"sysname", "operating system name"},
4203 {"nodename", "name of machine on network (implementation-defined)"},
4204 {"release", "operating system release"},
4205 {"version", "operating system version"},
4206 {"machine", "hardware identifier"},
4207 {NULL}
4208};
4209
4210PyDoc_STRVAR(uname_result__doc__,
4211"uname_result: Result from os.uname().\n\n\
4212This object may be accessed either as a tuple of\n\
4213 (sysname, nodename, release, version, machine),\n\
4214or via the attributes sysname, nodename, release, version, and machine.\n\
4215\n\
4216See os.uname for more information.");
4217
4218static PyStructSequence_Desc uname_result_desc = {
4219 "uname_result", /* name */
4220 uname_result__doc__, /* doc */
4221 uname_result_fields,
4222 5
4223};
4224
4225static PyTypeObject UnameResultType;
4226
4227
4228#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004229static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004230posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004231{
Victor Stinner8c62be82010-05-06 00:08:46 +00004232 struct utsname u;
4233 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004234 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004235
Victor Stinner8c62be82010-05-06 00:08:46 +00004236 Py_BEGIN_ALLOW_THREADS
4237 res = uname(&u);
4238 Py_END_ALLOW_THREADS
4239 if (res < 0)
4240 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004241
4242 value = PyStructSequence_New(&UnameResultType);
4243 if (value == NULL)
4244 return NULL;
4245
4246#define SET(i, field) \
4247 { \
4248 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4249 if (!o) { \
4250 Py_DECREF(value); \
4251 return NULL; \
4252 } \
4253 PyStructSequence_SET_ITEM(value, i, o); \
4254 } \
4255
4256 SET(0, u.sysname);
4257 SET(1, u.nodename);
4258 SET(2, u.release);
4259 SET(3, u.version);
4260 SET(4, u.machine);
4261
4262#undef SET
4263
4264 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004265}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004266#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004267
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004268
Larry Hastings9cf065c2012-06-22 16:30:09 -07004269PyDoc_STRVAR(posix_utime__doc__,
4270"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4271Set the access and modified time of path.\n\
4272\n\
4273path may always be specified as a string.\n\
4274On some platforms, path may also be specified as an open file descriptor.\n\
4275 If this functionality is unavailable, using it raises an exception.\n\
4276\n\
4277If times is not None, it must be a tuple (atime, mtime);\n\
4278 atime and mtime should be expressed as float seconds since the epoch.\n\
4279If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4280 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4281 since the epoch.\n\
4282If both times and ns are None, utime uses the current time.\n\
4283Specifying tuples for both times and ns is an error.\n\
4284\n\
4285If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4286 and path should be relative; path will then be relative to that directory.\n\
4287If follow_symlinks is False, and the last element of the path is a symbolic\n\
4288 link, utime will modify the symbolic link itself instead of the file the\n\
4289 link points to.\n\
4290It is an error to use dir_fd or follow_symlinks when specifying path\n\
4291 as an open file descriptor.\n\
4292dir_fd and follow_symlinks may not be available on your platform.\n\
4293 If they are unavailable, using them will raise a NotImplementedError.");
4294
4295typedef struct {
4296 int now;
4297 time_t atime_s;
4298 long atime_ns;
4299 time_t mtime_s;
4300 long mtime_ns;
4301} utime_t;
4302
4303/*
4304 * these macros assume that "utime" is a pointer to a utime_t
4305 * they also intentionally leak the declaration of a pointer named "time"
4306 */
4307#define UTIME_TO_TIMESPEC \
4308 struct timespec ts[2]; \
4309 struct timespec *time; \
4310 if (utime->now) \
4311 time = NULL; \
4312 else { \
4313 ts[0].tv_sec = utime->atime_s; \
4314 ts[0].tv_nsec = utime->atime_ns; \
4315 ts[1].tv_sec = utime->mtime_s; \
4316 ts[1].tv_nsec = utime->mtime_ns; \
4317 time = ts; \
4318 } \
4319
4320#define UTIME_TO_TIMEVAL \
4321 struct timeval tv[2]; \
4322 struct timeval *time; \
4323 if (utime->now) \
4324 time = NULL; \
4325 else { \
4326 tv[0].tv_sec = utime->atime_s; \
4327 tv[0].tv_usec = utime->atime_ns / 1000; \
4328 tv[1].tv_sec = utime->mtime_s; \
4329 tv[1].tv_usec = utime->mtime_ns / 1000; \
4330 time = tv; \
4331 } \
4332
4333#define UTIME_TO_UTIMBUF \
4334 struct utimbuf u[2]; \
4335 struct utimbuf *time; \
4336 if (utime->now) \
4337 time = NULL; \
4338 else { \
4339 u.actime = utime->atime_s; \
4340 u.modtime = utime->mtime_s; \
4341 time = u; \
4342 }
4343
4344#define UTIME_TO_TIME_T \
4345 time_t timet[2]; \
4346 struct timet time; \
4347 if (utime->now) \
4348 time = NULL; \
4349 else { \
4350 timet[0] = utime->atime_s; \
4351 timet[1] = utime->mtime_s; \
4352 time = &timet; \
4353 } \
4354
4355
4356#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4357
4358#if UTIME_HAVE_DIR_FD
4359
4360static int
4361utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4362{
4363#ifdef HAVE_UTIMENSAT
4364 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4365 UTIME_TO_TIMESPEC;
4366 return utimensat(dir_fd, path, time, flags);
4367#elif defined(HAVE_FUTIMESAT)
4368 UTIME_TO_TIMEVAL;
4369 /*
4370 * follow_symlinks will never be false here;
4371 * we only allow !follow_symlinks and dir_fd together
4372 * if we have utimensat()
4373 */
4374 assert(follow_symlinks);
4375 return futimesat(dir_fd, path, time);
4376#endif
4377}
4378
4379#endif
4380
4381#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4382
4383#if UTIME_HAVE_FD
4384
4385static int
4386utime_fd(utime_t *utime, int fd)
4387{
4388#ifdef HAVE_FUTIMENS
4389 UTIME_TO_TIMESPEC;
4390 return futimens(fd, time);
4391#else
4392 UTIME_TO_TIMEVAL;
4393 return futimes(fd, time);
4394#endif
4395}
4396
4397#endif
4398
4399
4400#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4401 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4402
4403#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4404
4405static int
4406utime_nofollow_symlinks(utime_t *utime, char *path)
4407{
4408#ifdef HAVE_UTIMENSAT
4409 UTIME_TO_TIMESPEC;
4410 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4411#else
4412 UTIME_TO_TIMEVAL;
4413 return lutimes(path, time);
4414#endif
4415}
4416
4417#endif
4418
4419#ifndef MS_WINDOWS
4420
4421static int
4422utime_default(utime_t *utime, char *path)
4423{
4424#ifdef HAVE_UTIMENSAT
4425 UTIME_TO_TIMESPEC;
4426 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4427#elif defined(HAVE_UTIMES)
4428 UTIME_TO_TIMEVAL;
4429 return utimes(path, time);
4430#elif defined(HAVE_UTIME_H)
4431 UTIME_TO_UTIMBUF;
4432 return utime(path, time);
4433#else
4434 UTIME_TO_TIME_T;
4435 return utime(path, time);
4436#endif
4437}
4438
4439#endif
4440
Larry Hastings76ad59b2012-05-03 00:30:07 -07004441static int
4442split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4443{
4444 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004445 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004446 divmod = PyNumber_Divmod(py_long, billion);
4447 if (!divmod)
4448 goto exit;
4449 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4450 if ((*s == -1) && PyErr_Occurred())
4451 goto exit;
4452 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004453 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004454 goto exit;
4455
4456 result = 1;
4457exit:
4458 Py_XDECREF(divmod);
4459 return result;
4460}
4461
Larry Hastings9cf065c2012-06-22 16:30:09 -07004462static PyObject *
4463posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004464{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004465 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004466 PyObject *times = NULL;
4467 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004468 int dir_fd = DEFAULT_DIR_FD;
4469 int follow_symlinks = 1;
4470 char *keywords[] = {"path", "times", "ns", "dir_fd",
4471 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004472
Larry Hastings9cf065c2012-06-22 16:30:09 -07004473 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004474
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475#ifdef MS_WINDOWS
4476 HANDLE hFile;
4477 FILETIME atime, mtime;
4478#else
4479 int result;
4480#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004481
Larry Hastings9cf065c2012-06-22 16:30:09 -07004482 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004483
Larry Hastings9cf065c2012-06-22 16:30:09 -07004484 memset(&path, 0, sizeof(path));
Victor Stinnerb024e842012-10-31 22:24:06 +01004485 path.function_name = "utime";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004486#if UTIME_HAVE_FD
4487 path.allow_fd = 1;
4488#endif
4489 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4490 "O&|O$OO&p:utime", keywords,
4491 path_converter, &path,
4492 &times, &ns,
4493#if UTIME_HAVE_DIR_FD
4494 dir_fd_converter, &dir_fd,
4495#else
4496 dir_fd_unavailable, &dir_fd,
4497#endif
4498 &follow_symlinks
4499 ))
4500 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004501
Larry Hastings9cf065c2012-06-22 16:30:09 -07004502 if (times && (times != Py_None) && ns) {
4503 PyErr_SetString(PyExc_ValueError,
4504 "utime: you may specify either 'times'"
4505 " or 'ns' but not both");
4506 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004507 }
4508
4509 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004510 time_t a_sec, m_sec;
4511 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004512 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004513 PyErr_SetString(PyExc_TypeError,
4514 "utime: 'times' must be either"
4515 " a tuple of two ints or None");
4516 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004517 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004519 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004520 &a_sec, &a_nsec) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004521 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004522 &m_sec, &m_nsec) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004523 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004524 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004525 utime.atime_s = a_sec;
4526 utime.atime_ns = a_nsec;
4527 utime.mtime_s = m_sec;
4528 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004529 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004530 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004531 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004532 PyErr_SetString(PyExc_TypeError,
4533 "utime: 'ns' must be a tuple of two ints");
4534 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004535 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004537 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004539 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540 &utime.mtime_s, &utime.mtime_ns)) {
4541 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004542 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543 }
4544 else {
4545 /* times and ns are both None/unspecified. use "now". */
4546 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004547 }
4548
Larry Hastings9cf065c2012-06-22 16:30:09 -07004549#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4550 if (follow_symlinks_specified("utime", follow_symlinks))
4551 goto exit;
4552#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004553
Larry Hastings9cf065c2012-06-22 16:30:09 -07004554 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4555 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4556 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4557 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004558
Larry Hastings9cf065c2012-06-22 16:30:09 -07004559#if !defined(HAVE_UTIMENSAT)
4560 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004561 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004562 "utime: cannot use dir_fd and follow_symlinks "
4563 "together on this platform");
4564 goto exit;
4565 }
4566#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004567
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004568#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004569 Py_BEGIN_ALLOW_THREADS
4570 if (path.wide)
4571 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004572 NULL, OPEN_EXISTING,
4573 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574 else
4575 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004576 NULL, OPEN_EXISTING,
4577 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578 Py_END_ALLOW_THREADS
4579 if (hFile == INVALID_HANDLE_VALUE) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004580 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004582 }
4583
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004585 SYSTEMTIME now;
4586 GetSystemTime(&now);
4587 if (!SystemTimeToFileTime(&now, &mtime) ||
4588 !SystemTimeToFileTime(&now, &atime)) {
Victor Stinnerb024e842012-10-31 22:24:06 +01004589 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004591 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004592 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004593 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4595 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004596 }
4597 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4598 /* Avoid putting the file name into the error here,
4599 as that may confuse the user into believing that
4600 something is wrong with the file, when it also
4601 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004602 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004603 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004604 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004605#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004607
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4609 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4610 result = utime_nofollow_symlinks(&utime, path.narrow);
4611 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004612#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613
4614#if UTIME_HAVE_DIR_FD
4615 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4616 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4617 else
4618#endif
4619
4620#if UTIME_HAVE_FD
4621 if (path.fd != -1)
4622 result = utime_fd(&utime, path.fd);
4623 else
4624#endif
4625
4626 result = utime_default(&utime, path.narrow);
4627
4628 Py_END_ALLOW_THREADS
4629
4630 if (result < 0) {
4631 /* see previous comment about not putting filename in error here */
4632 return_value = posix_error();
4633 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004634 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004635
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004636#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637
4638 Py_INCREF(Py_None);
4639 return_value = Py_None;
4640
4641exit:
4642 path_cleanup(&path);
4643#ifdef MS_WINDOWS
4644 if (hFile != INVALID_HANDLE_VALUE)
4645 CloseHandle(hFile);
4646#endif
4647 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004648}
4649
Guido van Rossum3b066191991-06-04 19:40:25 +00004650/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004651
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004652PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004653"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004654Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004655
Barry Warsaw53699e91996-12-10 23:23:01 +00004656static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004657posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004658{
Victor Stinner8c62be82010-05-06 00:08:46 +00004659 int sts;
4660 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4661 return NULL;
4662 _exit(sts);
4663 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004664}
4665
Martin v. Löwis114619e2002-10-07 06:44:21 +00004666#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4667static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004668free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004669{
Victor Stinner8c62be82010-05-06 00:08:46 +00004670 Py_ssize_t i;
4671 for (i = 0; i < count; i++)
4672 PyMem_Free(array[i]);
4673 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004674}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004675
Antoine Pitrou69f71142009-05-24 21:25:49 +00004676static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004677int fsconvert_strdup(PyObject *o, char**out)
4678{
Victor Stinner8c62be82010-05-06 00:08:46 +00004679 PyObject *bytes;
4680 Py_ssize_t size;
4681 if (!PyUnicode_FSConverter(o, &bytes))
4682 return 0;
4683 size = PyBytes_GET_SIZE(bytes);
4684 *out = PyMem_Malloc(size+1);
4685 if (!*out)
4686 return 0;
4687 memcpy(*out, PyBytes_AsString(bytes), size+1);
4688 Py_DECREF(bytes);
4689 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004690}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004691#endif
4692
Ross Lagerwall7807c352011-03-17 20:20:30 +02004693#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004694static char**
4695parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4696{
Victor Stinner8c62be82010-05-06 00:08:46 +00004697 char **envlist;
4698 Py_ssize_t i, pos, envc;
4699 PyObject *keys=NULL, *vals=NULL;
4700 PyObject *key, *val, *key2, *val2;
4701 char *p, *k, *v;
4702 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004703
Victor Stinner8c62be82010-05-06 00:08:46 +00004704 i = PyMapping_Size(env);
4705 if (i < 0)
4706 return NULL;
4707 envlist = PyMem_NEW(char *, i + 1);
4708 if (envlist == NULL) {
4709 PyErr_NoMemory();
4710 return NULL;
4711 }
4712 envc = 0;
4713 keys = PyMapping_Keys(env);
4714 vals = PyMapping_Values(env);
4715 if (!keys || !vals)
4716 goto error;
4717 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4718 PyErr_Format(PyExc_TypeError,
4719 "env.keys() or env.values() is not a list");
4720 goto error;
4721 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004722
Victor Stinner8c62be82010-05-06 00:08:46 +00004723 for (pos = 0; pos < i; pos++) {
4724 key = PyList_GetItem(keys, pos);
4725 val = PyList_GetItem(vals, pos);
4726 if (!key || !val)
4727 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004728
Victor Stinner8c62be82010-05-06 00:08:46 +00004729 if (PyUnicode_FSConverter(key, &key2) == 0)
4730 goto error;
4731 if (PyUnicode_FSConverter(val, &val2) == 0) {
4732 Py_DECREF(key2);
4733 goto error;
4734 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004735
Victor Stinner8c62be82010-05-06 00:08:46 +00004736 k = PyBytes_AsString(key2);
4737 v = PyBytes_AsString(val2);
4738 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004739
Victor Stinner8c62be82010-05-06 00:08:46 +00004740 p = PyMem_NEW(char, len);
4741 if (p == NULL) {
4742 PyErr_NoMemory();
4743 Py_DECREF(key2);
4744 Py_DECREF(val2);
4745 goto error;
4746 }
4747 PyOS_snprintf(p, len, "%s=%s", k, v);
4748 envlist[envc++] = p;
4749 Py_DECREF(key2);
4750 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004751 }
4752 Py_DECREF(vals);
4753 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004754
Victor Stinner8c62be82010-05-06 00:08:46 +00004755 envlist[envc] = 0;
4756 *envc_ptr = envc;
4757 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004758
4759error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004760 Py_XDECREF(keys);
4761 Py_XDECREF(vals);
4762 while (--envc >= 0)
4763 PyMem_DEL(envlist[envc]);
4764 PyMem_DEL(envlist);
4765 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004766}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004767
Ross Lagerwall7807c352011-03-17 20:20:30 +02004768static char**
4769parse_arglist(PyObject* argv, Py_ssize_t *argc)
4770{
4771 int i;
4772 char **argvlist = PyMem_NEW(char *, *argc+1);
4773 if (argvlist == NULL) {
4774 PyErr_NoMemory();
4775 return NULL;
4776 }
4777 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004778 PyObject* item = PySequence_ITEM(argv, i);
4779 if (item == NULL)
4780 goto fail;
4781 if (!fsconvert_strdup(item, &argvlist[i])) {
4782 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004783 goto fail;
4784 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004785 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004786 }
4787 argvlist[*argc] = NULL;
4788 return argvlist;
4789fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004790 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004791 free_string_array(argvlist, *argc);
4792 return NULL;
4793}
4794#endif
4795
4796#ifdef HAVE_EXECV
4797PyDoc_STRVAR(posix_execv__doc__,
4798"execv(path, args)\n\n\
4799Execute an executable path with arguments, replacing current process.\n\
4800\n\
4801 path: path of executable file\n\
4802 args: tuple or list of strings");
4803
4804static PyObject *
4805posix_execv(PyObject *self, PyObject *args)
4806{
4807 PyObject *opath;
4808 char *path;
4809 PyObject *argv;
4810 char **argvlist;
4811 Py_ssize_t argc;
4812
4813 /* execv has two arguments: (path, argv), where
4814 argv is a list or tuple of strings. */
4815
4816 if (!PyArg_ParseTuple(args, "O&O:execv",
4817 PyUnicode_FSConverter,
4818 &opath, &argv))
4819 return NULL;
4820 path = PyBytes_AsString(opath);
4821 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4822 PyErr_SetString(PyExc_TypeError,
4823 "execv() arg 2 must be a tuple or list");
4824 Py_DECREF(opath);
4825 return NULL;
4826 }
4827 argc = PySequence_Size(argv);
4828 if (argc < 1) {
4829 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4830 Py_DECREF(opath);
4831 return NULL;
4832 }
4833
4834 argvlist = parse_arglist(argv, &argc);
4835 if (argvlist == NULL) {
4836 Py_DECREF(opath);
4837 return NULL;
4838 }
4839
4840 execv(path, argvlist);
4841
4842 /* If we get here it's definitely an error */
4843
4844 free_string_array(argvlist, argc);
4845 Py_DECREF(opath);
4846 return posix_error();
4847}
4848
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004849PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004850"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004851Execute a path with arguments and environment, replacing current process.\n\
4852\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004853 path: path of executable file\n\
4854 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004855 env: dictionary of strings mapping to strings\n\
4856\n\
4857On some platforms, you may specify an open file descriptor for path;\n\
4858 execve will execute the program the file descriptor is open to.\n\
4859 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004860
Barry Warsaw53699e91996-12-10 23:23:01 +00004861static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004863{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004864 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004865 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004866 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004868 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004869 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004870
Victor Stinner8c62be82010-05-06 00:08:46 +00004871 /* execve has three arguments: (path, argv, env), where
4872 argv is a list or tuple of strings and env is a dictionary
4873 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004874
Larry Hastings9cf065c2012-06-22 16:30:09 -07004875 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01004876 path.function_name = "execve";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004877#ifdef HAVE_FEXECVE
4878 path.allow_fd = 1;
4879#endif
4880 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4881 path_converter, &path,
4882 &argv, &env
4883 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004885
Ross Lagerwall7807c352011-03-17 20:20:30 +02004886 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004887 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004888 "execve: argv must be a tuple or list");
4889 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004891 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004892 if (!PyMapping_Check(env)) {
4893 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004894 "execve: environment must be a mapping object");
4895 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004896 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004897
Ross Lagerwall7807c352011-03-17 20:20:30 +02004898 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004900 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004901 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004902
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 envlist = parse_envlist(env, &envc);
4904 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004905 goto fail;
4906
Larry Hastings9cf065c2012-06-22 16:30:09 -07004907#ifdef HAVE_FEXECVE
4908 if (path.fd > -1)
4909 fexecve(path.fd, argvlist, envlist);
4910 else
4911#endif
4912 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004913
4914 /* If we get here it's definitely an error */
4915
Victor Stinner292c8352012-10-30 02:17:38 +01004916 path_error(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004917
4918 while (--envc >= 0)
4919 PyMem_DEL(envlist[envc]);
4920 PyMem_DEL(envlist);
4921 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004922 if (argvlist)
4923 free_string_array(argvlist, argc);
4924 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004925 return NULL;
4926}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927#endif /* HAVE_EXECV */
4928
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004929
Guido van Rossuma1065681999-01-25 23:20:23 +00004930#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004931PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004932"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004933Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004934\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004935 mode: mode of process creation\n\
4936 path: path of executable file\n\
4937 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004938
4939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004940posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004941{
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 PyObject *opath;
4943 char *path;
4944 PyObject *argv;
4945 char **argvlist;
4946 int mode, i;
4947 Py_ssize_t argc;
4948 Py_intptr_t spawnval;
4949 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004950
Victor Stinner8c62be82010-05-06 00:08:46 +00004951 /* spawnv has three arguments: (mode, path, argv), where
4952 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004953
Victor Stinner8c62be82010-05-06 00:08:46 +00004954 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4955 PyUnicode_FSConverter,
4956 &opath, &argv))
4957 return NULL;
4958 path = PyBytes_AsString(opath);
4959 if (PyList_Check(argv)) {
4960 argc = PyList_Size(argv);
4961 getitem = PyList_GetItem;
4962 }
4963 else if (PyTuple_Check(argv)) {
4964 argc = PyTuple_Size(argv);
4965 getitem = PyTuple_GetItem;
4966 }
4967 else {
4968 PyErr_SetString(PyExc_TypeError,
4969 "spawnv() arg 2 must be a tuple or list");
4970 Py_DECREF(opath);
4971 return NULL;
4972 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004973
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 argvlist = PyMem_NEW(char *, argc+1);
4975 if (argvlist == NULL) {
4976 Py_DECREF(opath);
4977 return PyErr_NoMemory();
4978 }
4979 for (i = 0; i < argc; i++) {
4980 if (!fsconvert_strdup((*getitem)(argv, i),
4981 &argvlist[i])) {
4982 free_string_array(argvlist, i);
4983 PyErr_SetString(
4984 PyExc_TypeError,
4985 "spawnv() arg 2 must contain only strings");
4986 Py_DECREF(opath);
4987 return NULL;
4988 }
4989 }
4990 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004991
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 if (mode == _OLD_P_OVERLAY)
4993 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004994
Victor Stinner8c62be82010-05-06 00:08:46 +00004995 Py_BEGIN_ALLOW_THREADS
4996 spawnval = _spawnv(mode, path, argvlist);
4997 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00004998
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 free_string_array(argvlist, argc);
5000 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005001
Victor Stinner8c62be82010-05-06 00:08:46 +00005002 if (spawnval == -1)
5003 return posix_error();
5004 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005005#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005006 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005007#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005008 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005009#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005010}
5011
5012
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005013PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005014"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005015Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005016\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 mode: mode of process creation\n\
5018 path: path of executable file\n\
5019 args: tuple or list of arguments\n\
5020 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005021
5022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005023posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005024{
Victor Stinner8c62be82010-05-06 00:08:46 +00005025 PyObject *opath;
5026 char *path;
5027 PyObject *argv, *env;
5028 char **argvlist;
5029 char **envlist;
5030 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005031 int mode;
5032 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005033 Py_intptr_t spawnval;
5034 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5035 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005036
Victor Stinner8c62be82010-05-06 00:08:46 +00005037 /* spawnve has four arguments: (mode, path, argv, env), where
5038 argv is a list or tuple of strings and env is a dictionary
5039 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005040
Victor Stinner8c62be82010-05-06 00:08:46 +00005041 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5042 PyUnicode_FSConverter,
5043 &opath, &argv, &env))
5044 return NULL;
5045 path = PyBytes_AsString(opath);
5046 if (PyList_Check(argv)) {
5047 argc = PyList_Size(argv);
5048 getitem = PyList_GetItem;
5049 }
5050 else if (PyTuple_Check(argv)) {
5051 argc = PyTuple_Size(argv);
5052 getitem = PyTuple_GetItem;
5053 }
5054 else {
5055 PyErr_SetString(PyExc_TypeError,
5056 "spawnve() arg 2 must be a tuple or list");
5057 goto fail_0;
5058 }
5059 if (!PyMapping_Check(env)) {
5060 PyErr_SetString(PyExc_TypeError,
5061 "spawnve() arg 3 must be a mapping object");
5062 goto fail_0;
5063 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005064
Victor Stinner8c62be82010-05-06 00:08:46 +00005065 argvlist = PyMem_NEW(char *, argc+1);
5066 if (argvlist == NULL) {
5067 PyErr_NoMemory();
5068 goto fail_0;
5069 }
5070 for (i = 0; i < argc; i++) {
5071 if (!fsconvert_strdup((*getitem)(argv, i),
5072 &argvlist[i]))
5073 {
5074 lastarg = i;
5075 goto fail_1;
5076 }
5077 }
5078 lastarg = argc;
5079 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005080
Victor Stinner8c62be82010-05-06 00:08:46 +00005081 envlist = parse_envlist(env, &envc);
5082 if (envlist == NULL)
5083 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005084
Victor Stinner8c62be82010-05-06 00:08:46 +00005085 if (mode == _OLD_P_OVERLAY)
5086 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005087
Victor Stinner8c62be82010-05-06 00:08:46 +00005088 Py_BEGIN_ALLOW_THREADS
5089 spawnval = _spawnve(mode, path, argvlist, envlist);
5090 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005091
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 if (spawnval == -1)
5093 (void) posix_error();
5094 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005095#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005097#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005098 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005099#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005100
Victor Stinner8c62be82010-05-06 00:08:46 +00005101 while (--envc >= 0)
5102 PyMem_DEL(envlist[envc]);
5103 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005104 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005106 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 Py_DECREF(opath);
5108 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005109}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005110
Guido van Rossuma1065681999-01-25 23:20:23 +00005111#endif /* HAVE_SPAWNV */
5112
5113
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005114#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005115PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005116"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005117Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5118\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005119Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005120
5121static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005122posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005123{
Victor Stinner8c62be82010-05-06 00:08:46 +00005124 pid_t pid;
5125 int result = 0;
5126 _PyImport_AcquireLock();
5127 pid = fork1();
5128 if (pid == 0) {
5129 /* child: this clobbers and resets the import lock. */
5130 PyOS_AfterFork();
5131 } else {
5132 /* parent: release the import lock. */
5133 result = _PyImport_ReleaseLock();
5134 }
5135 if (pid == -1)
5136 return posix_error();
5137 if (result < 0) {
5138 /* Don't clobber the OSError if the fork failed. */
5139 PyErr_SetString(PyExc_RuntimeError,
5140 "not holding the import lock");
5141 return NULL;
5142 }
5143 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005144}
5145#endif
5146
5147
Guido van Rossumad0ee831995-03-01 10:34:45 +00005148#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005149PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005150"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005151Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005152Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005153
Barry Warsaw53699e91996-12-10 23:23:01 +00005154static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005155posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005156{
Victor Stinner8c62be82010-05-06 00:08:46 +00005157 pid_t pid;
5158 int result = 0;
5159 _PyImport_AcquireLock();
5160 pid = fork();
5161 if (pid == 0) {
5162 /* child: this clobbers and resets the import lock. */
5163 PyOS_AfterFork();
5164 } else {
5165 /* parent: release the import lock. */
5166 result = _PyImport_ReleaseLock();
5167 }
5168 if (pid == -1)
5169 return posix_error();
5170 if (result < 0) {
5171 /* Don't clobber the OSError if the fork failed. */
5172 PyErr_SetString(PyExc_RuntimeError,
5173 "not holding the import lock");
5174 return NULL;
5175 }
5176 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005177}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005178#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005179
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005180#ifdef HAVE_SCHED_H
5181
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005182#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5183
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005184PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5185"sched_get_priority_max(policy)\n\n\
5186Get the maximum scheduling priority for *policy*.");
5187
5188static PyObject *
5189posix_sched_get_priority_max(PyObject *self, PyObject *args)
5190{
5191 int policy, max;
5192
5193 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5194 return NULL;
5195 max = sched_get_priority_max(policy);
5196 if (max < 0)
5197 return posix_error();
5198 return PyLong_FromLong(max);
5199}
5200
5201PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5202"sched_get_priority_min(policy)\n\n\
5203Get the minimum scheduling priority for *policy*.");
5204
5205static PyObject *
5206posix_sched_get_priority_min(PyObject *self, PyObject *args)
5207{
5208 int policy, min;
5209
5210 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5211 return NULL;
5212 min = sched_get_priority_min(policy);
5213 if (min < 0)
5214 return posix_error();
5215 return PyLong_FromLong(min);
5216}
5217
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005218#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5219
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005220#ifdef HAVE_SCHED_SETSCHEDULER
5221
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005222PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5223"sched_getscheduler(pid)\n\n\
5224Get the scheduling policy for the process with a PID of *pid*.\n\
5225Passing a PID of 0 returns the scheduling policy for the calling process.");
5226
5227static PyObject *
5228posix_sched_getscheduler(PyObject *self, PyObject *args)
5229{
5230 pid_t pid;
5231 int policy;
5232
5233 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5234 return NULL;
5235 policy = sched_getscheduler(pid);
5236 if (policy < 0)
5237 return posix_error();
5238 return PyLong_FromLong(policy);
5239}
5240
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005241#endif
5242
5243#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5244
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005245static PyObject *
5246sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5247{
5248 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005249 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005250
5251 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5252 return NULL;
5253 res = PyStructSequence_New(type);
5254 if (!res)
5255 return NULL;
5256 Py_INCREF(priority);
5257 PyStructSequence_SET_ITEM(res, 0, priority);
5258 return res;
5259}
5260
5261PyDoc_STRVAR(sched_param__doc__,
5262"sched_param(sched_priority): A scheduling parameter.\n\n\
5263Current has only one field: sched_priority");
5264
5265static PyStructSequence_Field sched_param_fields[] = {
5266 {"sched_priority", "the scheduling priority"},
5267 {0}
5268};
5269
5270static PyStructSequence_Desc sched_param_desc = {
5271 "sched_param", /* name */
5272 sched_param__doc__, /* doc */
5273 sched_param_fields,
5274 1
5275};
5276
5277static int
5278convert_sched_param(PyObject *param, struct sched_param *res)
5279{
5280 long priority;
5281
5282 if (Py_TYPE(param) != &SchedParamType) {
5283 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5284 return 0;
5285 }
5286 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5287 if (priority == -1 && PyErr_Occurred())
5288 return 0;
5289 if (priority > INT_MAX || priority < INT_MIN) {
5290 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5291 return 0;
5292 }
5293 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5294 return 1;
5295}
5296
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005297#endif
5298
5299#ifdef HAVE_SCHED_SETSCHEDULER
5300
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005301PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5302"sched_setscheduler(pid, policy, param)\n\n\
5303Set the scheduling policy, *policy*, for *pid*.\n\
5304If *pid* is 0, the calling process is changed.\n\
5305*param* is an instance of sched_param.");
5306
5307static PyObject *
5308posix_sched_setscheduler(PyObject *self, PyObject *args)
5309{
5310 pid_t pid;
5311 int policy;
5312 struct sched_param param;
5313
5314 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5315 &pid, &policy, &convert_sched_param, &param))
5316 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005317
5318 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005319 ** sched_setscheduler() returns 0 in Linux, but the previous
5320 ** scheduling policy under Solaris/Illumos, and others.
5321 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005322 */
5323 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005324 return posix_error();
5325 Py_RETURN_NONE;
5326}
5327
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005328#endif
5329
5330#ifdef HAVE_SCHED_SETPARAM
5331
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005332PyDoc_STRVAR(posix_sched_getparam__doc__,
5333"sched_getparam(pid) -> sched_param\n\n\
5334Returns scheduling parameters for the process with *pid* as an instance of the\n\
5335sched_param class. A PID of 0 means the calling process.");
5336
5337static PyObject *
5338posix_sched_getparam(PyObject *self, PyObject *args)
5339{
5340 pid_t pid;
5341 struct sched_param param;
5342 PyObject *res, *priority;
5343
5344 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5345 return NULL;
5346 if (sched_getparam(pid, &param))
5347 return posix_error();
5348 res = PyStructSequence_New(&SchedParamType);
5349 if (!res)
5350 return NULL;
5351 priority = PyLong_FromLong(param.sched_priority);
5352 if (!priority) {
5353 Py_DECREF(res);
5354 return NULL;
5355 }
5356 PyStructSequence_SET_ITEM(res, 0, priority);
5357 return res;
5358}
5359
5360PyDoc_STRVAR(posix_sched_setparam__doc__,
5361"sched_setparam(pid, param)\n\n\
5362Set scheduling parameters for a process with PID *pid*.\n\
5363A PID of 0 means the calling process.");
5364
5365static PyObject *
5366posix_sched_setparam(PyObject *self, PyObject *args)
5367{
5368 pid_t pid;
5369 struct sched_param param;
5370
5371 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5372 &pid, &convert_sched_param, &param))
5373 return NULL;
5374 if (sched_setparam(pid, &param))
5375 return posix_error();
5376 Py_RETURN_NONE;
5377}
5378
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005379#endif
5380
5381#ifdef HAVE_SCHED_RR_GET_INTERVAL
5382
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005383PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5384"sched_rr_get_interval(pid) -> float\n\n\
5385Return the round-robin quantum for the process with PID *pid* in seconds.");
5386
5387static PyObject *
5388posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5389{
5390 pid_t pid;
5391 struct timespec interval;
5392
5393 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5394 return NULL;
5395 if (sched_rr_get_interval(pid, &interval))
5396 return posix_error();
5397 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5398}
5399
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005400#endif
5401
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005402PyDoc_STRVAR(posix_sched_yield__doc__,
5403"sched_yield()\n\n\
5404Voluntarily relinquish the CPU.");
5405
5406static PyObject *
5407posix_sched_yield(PyObject *self, PyObject *noargs)
5408{
5409 if (sched_yield())
5410 return posix_error();
5411 Py_RETURN_NONE;
5412}
5413
Benjamin Peterson2740af82011-08-02 17:41:34 -05005414#ifdef HAVE_SCHED_SETAFFINITY
5415
Antoine Pitrou84869872012-08-04 16:16:35 +02005416/* The minimum number of CPUs allocated in a cpu_set_t */
5417static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005418
5419PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5420"sched_setaffinity(pid, cpu_set)\n\n\
5421Set the affinity of the process with PID *pid* to *cpu_set*.");
5422
5423static PyObject *
5424posix_sched_setaffinity(PyObject *self, PyObject *args)
5425{
5426 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005427 int ncpus;
5428 size_t setsize;
5429 cpu_set_t *mask = NULL;
5430 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005431
Antoine Pitrou84869872012-08-04 16:16:35 +02005432 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5433 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005434 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005435
5436 iterator = PyObject_GetIter(iterable);
5437 if (iterator == NULL)
5438 return NULL;
5439
5440 ncpus = NCPUS_START;
5441 setsize = CPU_ALLOC_SIZE(ncpus);
5442 mask = CPU_ALLOC(ncpus);
5443 if (mask == NULL) {
5444 PyErr_NoMemory();
5445 goto error;
5446 }
5447 CPU_ZERO_S(setsize, mask);
5448
5449 while ((item = PyIter_Next(iterator))) {
5450 long cpu;
5451 if (!PyLong_Check(item)) {
5452 PyErr_Format(PyExc_TypeError,
5453 "expected an iterator of ints, "
5454 "but iterator yielded %R",
5455 Py_TYPE(item));
5456 Py_DECREF(item);
5457 goto error;
5458 }
5459 cpu = PyLong_AsLong(item);
5460 Py_DECREF(item);
5461 if (cpu < 0) {
5462 if (!PyErr_Occurred())
5463 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5464 goto error;
5465 }
5466 if (cpu > INT_MAX - 1) {
5467 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5468 goto error;
5469 }
5470 if (cpu >= ncpus) {
5471 /* Grow CPU mask to fit the CPU number */
5472 int newncpus = ncpus;
5473 cpu_set_t *newmask;
5474 size_t newsetsize;
5475 while (newncpus <= cpu) {
5476 if (newncpus > INT_MAX / 2)
5477 newncpus = cpu + 1;
5478 else
5479 newncpus = newncpus * 2;
5480 }
5481 newmask = CPU_ALLOC(newncpus);
5482 if (newmask == NULL) {
5483 PyErr_NoMemory();
5484 goto error;
5485 }
5486 newsetsize = CPU_ALLOC_SIZE(newncpus);
5487 CPU_ZERO_S(newsetsize, newmask);
5488 memcpy(newmask, mask, setsize);
5489 CPU_FREE(mask);
5490 setsize = newsetsize;
5491 mask = newmask;
5492 ncpus = newncpus;
5493 }
5494 CPU_SET_S(cpu, setsize, mask);
5495 }
5496 Py_CLEAR(iterator);
5497
5498 if (sched_setaffinity(pid, setsize, mask)) {
5499 posix_error();
5500 goto error;
5501 }
5502 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005503 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005504
5505error:
5506 if (mask)
5507 CPU_FREE(mask);
5508 Py_XDECREF(iterator);
5509 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005510}
5511
5512PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5513"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5514Return the affinity of the process with PID *pid*.\n\
5515The returned cpu_set will be of size *ncpus*.");
5516
5517static PyObject *
5518posix_sched_getaffinity(PyObject *self, PyObject *args)
5519{
5520 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005521 int cpu, ncpus, count;
5522 size_t setsize;
5523 cpu_set_t *mask = NULL;
5524 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005525
Antoine Pitrou84869872012-08-04 16:16:35 +02005526 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5527 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005528 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005529
5530 ncpus = NCPUS_START;
5531 while (1) {
5532 setsize = CPU_ALLOC_SIZE(ncpus);
5533 mask = CPU_ALLOC(ncpus);
5534 if (mask == NULL)
5535 return PyErr_NoMemory();
5536 if (sched_getaffinity(pid, setsize, mask) == 0)
5537 break;
5538 CPU_FREE(mask);
5539 if (errno != EINVAL)
5540 return posix_error();
5541 if (ncpus > INT_MAX / 2) {
5542 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5543 "a large enough CPU set");
5544 return NULL;
5545 }
5546 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005547 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005548
5549 res = PySet_New(NULL);
5550 if (res == NULL)
5551 goto error;
5552 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5553 if (CPU_ISSET_S(cpu, setsize, mask)) {
5554 PyObject *cpu_num = PyLong_FromLong(cpu);
5555 --count;
5556 if (cpu_num == NULL)
5557 goto error;
5558 if (PySet_Add(res, cpu_num)) {
5559 Py_DECREF(cpu_num);
5560 goto error;
5561 }
5562 Py_DECREF(cpu_num);
5563 }
5564 }
5565 CPU_FREE(mask);
5566 return res;
5567
5568error:
5569 if (mask)
5570 CPU_FREE(mask);
5571 Py_XDECREF(res);
5572 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005573}
5574
Benjamin Peterson2740af82011-08-02 17:41:34 -05005575#endif /* HAVE_SCHED_SETAFFINITY */
5576
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005577#endif /* HAVE_SCHED_H */
5578
Neal Norwitzb59798b2003-03-21 01:43:31 +00005579/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005580/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5581#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005582#define DEV_PTY_FILE "/dev/ptc"
5583#define HAVE_DEV_PTMX
5584#else
5585#define DEV_PTY_FILE "/dev/ptmx"
5586#endif
5587
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005588#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005589#ifdef HAVE_PTY_H
5590#include <pty.h>
5591#else
5592#ifdef HAVE_LIBUTIL_H
5593#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005594#else
5595#ifdef HAVE_UTIL_H
5596#include <util.h>
5597#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005598#endif /* HAVE_LIBUTIL_H */
5599#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005600#ifdef HAVE_STROPTS_H
5601#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005602#endif
5603#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005604
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005605#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005607"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005608Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005609
5610static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005611posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005612{
Victor Stinner8c62be82010-05-06 00:08:46 +00005613 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005614#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005615 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005616#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005617#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005618 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005619#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005620 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005621#endif
5622#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005623
Thomas Wouters70c21a12000-07-14 14:28:33 +00005624#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005625 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5626 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005627#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005628 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5629 if (slave_name == NULL)
5630 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005631
Victor Stinner8c62be82010-05-06 00:08:46 +00005632 slave_fd = open(slave_name, O_RDWR);
5633 if (slave_fd < 0)
5634 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005635#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005636 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5637 if (master_fd < 0)
5638 return posix_error();
5639 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5640 /* change permission of slave */
5641 if (grantpt(master_fd) < 0) {
5642 PyOS_setsig(SIGCHLD, sig_saved);
5643 return posix_error();
5644 }
5645 /* unlock slave */
5646 if (unlockpt(master_fd) < 0) {
5647 PyOS_setsig(SIGCHLD, sig_saved);
5648 return posix_error();
5649 }
5650 PyOS_setsig(SIGCHLD, sig_saved);
5651 slave_name = ptsname(master_fd); /* get name of slave */
5652 if (slave_name == NULL)
5653 return posix_error();
5654 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5655 if (slave_fd < 0)
5656 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005657#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005658 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5659 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005660#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005661 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005662#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005663#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005664#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005665
Victor Stinner8c62be82010-05-06 00:08:46 +00005666 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005667
Fred Drake8cef4cf2000-06-28 16:40:38 +00005668}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005669#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005670
5671#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005672PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005673"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005674Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5675Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005676To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005677
5678static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005679posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005680{
Victor Stinner8c62be82010-05-06 00:08:46 +00005681 int master_fd = -1, result = 0;
5682 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005683
Victor Stinner8c62be82010-05-06 00:08:46 +00005684 _PyImport_AcquireLock();
5685 pid = forkpty(&master_fd, NULL, NULL, NULL);
5686 if (pid == 0) {
5687 /* child: this clobbers and resets the import lock. */
5688 PyOS_AfterFork();
5689 } else {
5690 /* parent: release the import lock. */
5691 result = _PyImport_ReleaseLock();
5692 }
5693 if (pid == -1)
5694 return posix_error();
5695 if (result < 0) {
5696 /* Don't clobber the OSError if the fork failed. */
5697 PyErr_SetString(PyExc_RuntimeError,
5698 "not holding the import lock");
5699 return NULL;
5700 }
5701 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005702}
5703#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005704
Ross Lagerwall7807c352011-03-17 20:20:30 +02005705
Guido van Rossumad0ee831995-03-01 10:34:45 +00005706#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005707PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005708"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005709Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005710
Barry Warsaw53699e91996-12-10 23:23:01 +00005711static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005712posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005713{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005714 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005715}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005716#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005718
Guido van Rossumad0ee831995-03-01 10:34:45 +00005719#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005720PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005721"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005722Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005723
Barry Warsaw53699e91996-12-10 23:23:01 +00005724static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005725posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005726{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005727 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005728}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005729#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005730
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005731
Guido van Rossumad0ee831995-03-01 10:34:45 +00005732#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005733PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005734"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005735Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005736
Barry Warsaw53699e91996-12-10 23:23:01 +00005737static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005738posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005739{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005740 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005741}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005742#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005743
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005745PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005746"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005747Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005748
Barry Warsaw53699e91996-12-10 23:23:01 +00005749static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005750posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005751{
Victor Stinner8c62be82010-05-06 00:08:46 +00005752 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005753}
5754
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005755#ifdef HAVE_GETGROUPLIST
5756PyDoc_STRVAR(posix_getgrouplist__doc__,
5757"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5758Returns a list of groups to which a user belongs.\n\n\
5759 user: username to lookup\n\
5760 group: base group id of the user");
5761
5762static PyObject *
5763posix_getgrouplist(PyObject *self, PyObject *args)
5764{
5765#ifdef NGROUPS_MAX
5766#define MAX_GROUPS NGROUPS_MAX
5767#else
5768 /* defined to be 16 on Solaris7, so this should be a small number */
5769#define MAX_GROUPS 64
5770#endif
5771
5772 const char *user;
5773 int i, ngroups;
5774 PyObject *list;
5775#ifdef __APPLE__
5776 int *groups, basegid;
5777#else
5778 gid_t *groups, basegid;
5779#endif
5780 ngroups = MAX_GROUPS;
5781
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005782#ifdef __APPLE__
5783 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005784 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005785#else
5786 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
5787 _Py_Gid_Converter, &basegid))
5788 return NULL;
5789#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005790
5791#ifdef __APPLE__
5792 groups = PyMem_Malloc(ngroups * sizeof(int));
5793#else
5794 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5795#endif
5796 if (groups == NULL)
5797 return PyErr_NoMemory();
5798
5799 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5800 PyMem_Del(groups);
5801 return posix_error();
5802 }
5803
5804 list = PyList_New(ngroups);
5805 if (list == NULL) {
5806 PyMem_Del(groups);
5807 return NULL;
5808 }
5809
5810 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005811#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005812 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005813#else
5814 PyObject *o = _PyLong_FromGid(groups[i]);
5815#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005816 if (o == NULL) {
5817 Py_DECREF(list);
5818 PyMem_Del(groups);
5819 return NULL;
5820 }
5821 PyList_SET_ITEM(list, i, o);
5822 }
5823
5824 PyMem_Del(groups);
5825
5826 return list;
5827}
5828#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005829
Fred Drakec9680921999-12-13 16:37:25 +00005830#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005831PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005832"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005833Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005834
5835static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005836posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005837{
5838 PyObject *result = NULL;
5839
Fred Drakec9680921999-12-13 16:37:25 +00005840#ifdef NGROUPS_MAX
5841#define MAX_GROUPS NGROUPS_MAX
5842#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005843 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005844#define MAX_GROUPS 64
5845#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005846 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005847
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005848 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005849 * This is a helper variable to store the intermediate result when
5850 * that happens.
5851 *
5852 * To keep the code readable the OSX behaviour is unconditional,
5853 * according to the POSIX spec this should be safe on all unix-y
5854 * systems.
5855 */
5856 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005857 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005858
Victor Stinner8c62be82010-05-06 00:08:46 +00005859 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005860 if (n < 0) {
5861 if (errno == EINVAL) {
5862 n = getgroups(0, NULL);
5863 if (n == -1) {
5864 return posix_error();
5865 }
5866 if (n == 0) {
5867 /* Avoid malloc(0) */
5868 alt_grouplist = grouplist;
5869 } else {
5870 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5871 if (alt_grouplist == NULL) {
5872 errno = EINVAL;
5873 return posix_error();
5874 }
5875 n = getgroups(n, alt_grouplist);
5876 if (n == -1) {
5877 PyMem_Free(alt_grouplist);
5878 return posix_error();
5879 }
5880 }
5881 } else {
5882 return posix_error();
5883 }
5884 }
5885 result = PyList_New(n);
5886 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005887 int i;
5888 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005889 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005891 Py_DECREF(result);
5892 result = NULL;
5893 break;
Fred Drakec9680921999-12-13 16:37:25 +00005894 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005895 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005896 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005897 }
5898
5899 if (alt_grouplist != grouplist) {
5900 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005901 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005902
Fred Drakec9680921999-12-13 16:37:25 +00005903 return result;
5904}
5905#endif
5906
Antoine Pitroub7572f02009-12-02 20:46:48 +00005907#ifdef HAVE_INITGROUPS
5908PyDoc_STRVAR(posix_initgroups__doc__,
5909"initgroups(username, gid) -> None\n\n\
5910Call the system initgroups() to initialize the group access list with all of\n\
5911the groups of which the specified username is a member, plus the specified\n\
5912group id.");
5913
5914static PyObject *
5915posix_initgroups(PyObject *self, PyObject *args)
5916{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005917 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005919 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005920#ifdef __APPLE__
5921 int gid;
5922#else
5923 gid_t gid;
5924#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00005925
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005926#ifdef __APPLE__
5927 if (!PyArg_ParseTuple(args, "O&i:initgroups",
5928 PyUnicode_FSConverter, &oname,
5929 &gid))
5930#else
5931 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
5932 PyUnicode_FSConverter, &oname,
5933 _Py_Gid_Converter, &gid))
5934#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005936 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005937
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005938 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005939 Py_DECREF(oname);
5940 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005941 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005942
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 Py_INCREF(Py_None);
5944 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005945}
5946#endif
5947
Martin v. Löwis606edc12002-06-13 21:09:11 +00005948#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005949PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005950"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005951Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005952
5953static PyObject *
5954posix_getpgid(PyObject *self, PyObject *args)
5955{
Victor Stinner8c62be82010-05-06 00:08:46 +00005956 pid_t pid, pgid;
5957 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5958 return NULL;
5959 pgid = getpgid(pid);
5960 if (pgid < 0)
5961 return posix_error();
5962 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005963}
5964#endif /* HAVE_GETPGID */
5965
5966
Guido van Rossumb6775db1994-08-01 11:34:53 +00005967#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005968PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005969"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005970Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005971
Barry Warsaw53699e91996-12-10 23:23:01 +00005972static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005973posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005974{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005975#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005976 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005977#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005978 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005979#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005980}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005981#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005982
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005983
Guido van Rossumb6775db1994-08-01 11:34:53 +00005984#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005985PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005986"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005987Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005988
Barry Warsaw53699e91996-12-10 23:23:01 +00005989static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005990posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005991{
Guido van Rossum64933891994-10-20 21:56:42 +00005992#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005993 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005994#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005995 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005996#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 return posix_error();
5998 Py_INCREF(Py_None);
5999 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006000}
6001
Guido van Rossumb6775db1994-08-01 11:34:53 +00006002#endif /* HAVE_SETPGRP */
6003
Guido van Rossumad0ee831995-03-01 10:34:45 +00006004#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006005
6006#ifdef MS_WINDOWS
6007#include <tlhelp32.h>
6008
6009static PyObject*
6010win32_getppid()
6011{
6012 HANDLE snapshot;
6013 pid_t mypid;
6014 PyObject* result = NULL;
6015 BOOL have_record;
6016 PROCESSENTRY32 pe;
6017
6018 mypid = getpid(); /* This function never fails */
6019
6020 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6021 if (snapshot == INVALID_HANDLE_VALUE)
6022 return PyErr_SetFromWindowsErr(GetLastError());
6023
6024 pe.dwSize = sizeof(pe);
6025 have_record = Process32First(snapshot, &pe);
6026 while (have_record) {
6027 if (mypid == (pid_t)pe.th32ProcessID) {
6028 /* We could cache the ulong value in a static variable. */
6029 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6030 break;
6031 }
6032
6033 have_record = Process32Next(snapshot, &pe);
6034 }
6035
6036 /* If our loop exits and our pid was not found (result will be NULL)
6037 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6038 * error anyway, so let's raise it. */
6039 if (!result)
6040 result = PyErr_SetFromWindowsErr(GetLastError());
6041
6042 CloseHandle(snapshot);
6043
6044 return result;
6045}
6046#endif /*MS_WINDOWS*/
6047
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006048PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006049"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006050Return the parent's process id. If the parent process has already exited,\n\
6051Windows machines will still return its id; others systems will return the id\n\
6052of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006053
Barry Warsaw53699e91996-12-10 23:23:01 +00006054static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006055posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006056{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006057#ifdef MS_WINDOWS
6058 return win32_getppid();
6059#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006060 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006061#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006062}
6063#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006064
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006065
Fred Drake12c6e2d1999-12-14 21:25:03 +00006066#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006067PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006068"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006069Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006070
6071static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006072posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006073{
Victor Stinner8c62be82010-05-06 00:08:46 +00006074 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006075#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006076 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006077 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006078
6079 if (GetUserNameW(user_name, &num_chars)) {
6080 /* num_chars is the number of unicode chars plus null terminator */
6081 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006082 }
6083 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006084 result = PyErr_SetFromWindowsErr(GetLastError());
6085#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006086 char *name;
6087 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006088
Victor Stinner8c62be82010-05-06 00:08:46 +00006089 errno = 0;
6090 name = getlogin();
6091 if (name == NULL) {
6092 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006093 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006094 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006095 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006096 }
6097 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006098 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006099 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006100#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006101 return result;
6102}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006103#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006104
Guido van Rossumad0ee831995-03-01 10:34:45 +00006105#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006106PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006107"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006108Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006109
Barry Warsaw53699e91996-12-10 23:23:01 +00006110static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006111posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006112{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006113 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006114}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006115#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006116
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006117
Guido van Rossumad0ee831995-03-01 10:34:45 +00006118#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006119PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006120"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006122
Barry Warsaw53699e91996-12-10 23:23:01 +00006123static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006124posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006125{
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 pid_t pid;
6127 int sig;
6128 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6129 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 if (kill(pid, sig) == -1)
6131 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006132 Py_INCREF(Py_None);
6133 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006134}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006135#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006136
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006137#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006138PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006139"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006140Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006141
6142static PyObject *
6143posix_killpg(PyObject *self, PyObject *args)
6144{
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 int sig;
6146 pid_t pgid;
6147 /* XXX some man pages make the `pgid` parameter an int, others
6148 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6149 take the same type. Moreover, pid_t is always at least as wide as
6150 int (else compilation of this module fails), which is safe. */
6151 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6152 return NULL;
6153 if (killpg(pgid, sig) == -1)
6154 return posix_error();
6155 Py_INCREF(Py_None);
6156 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006157}
6158#endif
6159
Brian Curtineb24d742010-04-12 17:16:38 +00006160#ifdef MS_WINDOWS
6161PyDoc_STRVAR(win32_kill__doc__,
6162"kill(pid, sig)\n\n\
6163Kill a process with a signal.");
6164
6165static PyObject *
6166win32_kill(PyObject *self, PyObject *args)
6167{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006168 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006169 DWORD pid, sig, err;
6170 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006171
Victor Stinner8c62be82010-05-06 00:08:46 +00006172 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6173 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006174
Victor Stinner8c62be82010-05-06 00:08:46 +00006175 /* Console processes which share a common console can be sent CTRL+C or
6176 CTRL+BREAK events, provided they handle said events. */
6177 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6178 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6179 err = GetLastError();
6180 PyErr_SetFromWindowsErr(err);
6181 }
6182 else
6183 Py_RETURN_NONE;
6184 }
Brian Curtineb24d742010-04-12 17:16:38 +00006185
Victor Stinner8c62be82010-05-06 00:08:46 +00006186 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6187 attempt to open and terminate the process. */
6188 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6189 if (handle == NULL) {
6190 err = GetLastError();
6191 return PyErr_SetFromWindowsErr(err);
6192 }
Brian Curtineb24d742010-04-12 17:16:38 +00006193
Victor Stinner8c62be82010-05-06 00:08:46 +00006194 if (TerminateProcess(handle, sig) == 0) {
6195 err = GetLastError();
6196 result = PyErr_SetFromWindowsErr(err);
6197 } else {
6198 Py_INCREF(Py_None);
6199 result = Py_None;
6200 }
Brian Curtineb24d742010-04-12 17:16:38 +00006201
Victor Stinner8c62be82010-05-06 00:08:46 +00006202 CloseHandle(handle);
6203 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006204}
6205#endif /* MS_WINDOWS */
6206
Guido van Rossumc0125471996-06-28 18:55:32 +00006207#ifdef HAVE_PLOCK
6208
6209#ifdef HAVE_SYS_LOCK_H
6210#include <sys/lock.h>
6211#endif
6212
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006213PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006214"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006215Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006216
Barry Warsaw53699e91996-12-10 23:23:01 +00006217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006218posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006219{
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 int op;
6221 if (!PyArg_ParseTuple(args, "i:plock", &op))
6222 return NULL;
6223 if (plock(op) == -1)
6224 return posix_error();
6225 Py_INCREF(Py_None);
6226 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006227}
6228#endif
6229
Guido van Rossumb6775db1994-08-01 11:34:53 +00006230#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006231PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006232"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006233Set the current process's user id.");
6234
Barry Warsaw53699e91996-12-10 23:23:01 +00006235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006236posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006237{
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006239 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006240 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006241 if (setuid(uid) < 0)
6242 return posix_error();
6243 Py_INCREF(Py_None);
6244 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006245}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006246#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006247
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006248
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006249#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006250PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006251"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006252Set the current process's effective user id.");
6253
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006254static PyObject *
6255posix_seteuid (PyObject *self, PyObject *args)
6256{
Victor Stinner8c62be82010-05-06 00:08:46 +00006257 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006258 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006259 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006260 if (seteuid(euid) < 0) {
6261 return posix_error();
6262 } else {
6263 Py_INCREF(Py_None);
6264 return Py_None;
6265 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006266}
6267#endif /* HAVE_SETEUID */
6268
6269#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006270PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006271"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006272Set the current process's effective group id.");
6273
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006274static PyObject *
6275posix_setegid (PyObject *self, PyObject *args)
6276{
Victor Stinner8c62be82010-05-06 00:08:46 +00006277 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006278 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006280 if (setegid(egid) < 0) {
6281 return posix_error();
6282 } else {
6283 Py_INCREF(Py_None);
6284 return Py_None;
6285 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006286}
6287#endif /* HAVE_SETEGID */
6288
6289#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006290PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006291"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006292Set the current process's real and effective user ids.");
6293
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006294static PyObject *
6295posix_setreuid (PyObject *self, PyObject *args)
6296{
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006298 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6299 _Py_Uid_Converter, &ruid,
6300 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006301 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 if (setreuid(ruid, euid) < 0) {
6303 return posix_error();
6304 } else {
6305 Py_INCREF(Py_None);
6306 return Py_None;
6307 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006308}
6309#endif /* HAVE_SETREUID */
6310
6311#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006312PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006313"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006314Set the current process's real and effective group ids.");
6315
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006316static PyObject *
6317posix_setregid (PyObject *self, PyObject *args)
6318{
Victor Stinner8c62be82010-05-06 00:08:46 +00006319 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006320 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6321 _Py_Gid_Converter, &rgid,
6322 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006323 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 if (setregid(rgid, egid) < 0) {
6325 return posix_error();
6326 } else {
6327 Py_INCREF(Py_None);
6328 return Py_None;
6329 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006330}
6331#endif /* HAVE_SETREGID */
6332
Guido van Rossumb6775db1994-08-01 11:34:53 +00006333#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006334PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006335"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006336Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006337
Barry Warsaw53699e91996-12-10 23:23:01 +00006338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006339posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006340{
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006342 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 if (setgid(gid) < 0)
6345 return posix_error();
6346 Py_INCREF(Py_None);
6347 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006348}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006349#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006350
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006351#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006352PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006353"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006354Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006355
6356static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006357posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006358{
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 int i, len;
6360 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006361
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 if (!PySequence_Check(groups)) {
6363 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6364 return NULL;
6365 }
6366 len = PySequence_Size(groups);
6367 if (len > MAX_GROUPS) {
6368 PyErr_SetString(PyExc_ValueError, "too many groups");
6369 return NULL;
6370 }
6371 for(i = 0; i < len; i++) {
6372 PyObject *elem;
6373 elem = PySequence_GetItem(groups, i);
6374 if (!elem)
6375 return NULL;
6376 if (!PyLong_Check(elem)) {
6377 PyErr_SetString(PyExc_TypeError,
6378 "groups must be integers");
6379 Py_DECREF(elem);
6380 return NULL;
6381 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006382 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 Py_DECREF(elem);
6384 return NULL;
6385 }
6386 }
6387 Py_DECREF(elem);
6388 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006389
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 if (setgroups(len, grouplist) < 0)
6391 return posix_error();
6392 Py_INCREF(Py_None);
6393 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006394}
6395#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006396
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006397#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6398static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006399wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006400{
Victor Stinner8c62be82010-05-06 00:08:46 +00006401 PyObject *result;
6402 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006403 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006404
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 if (pid == -1)
6406 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006407
Victor Stinner8c62be82010-05-06 00:08:46 +00006408 if (struct_rusage == NULL) {
6409 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6410 if (m == NULL)
6411 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006412 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 Py_DECREF(m);
6414 if (struct_rusage == NULL)
6415 return NULL;
6416 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006417
Victor Stinner8c62be82010-05-06 00:08:46 +00006418 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6419 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6420 if (!result)
6421 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006422
6423#ifndef doubletime
6424#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6425#endif
6426
Victor Stinner8c62be82010-05-06 00:08:46 +00006427 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006428 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006429 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006430 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006431#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006432 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6433 SET_INT(result, 2, ru->ru_maxrss);
6434 SET_INT(result, 3, ru->ru_ixrss);
6435 SET_INT(result, 4, ru->ru_idrss);
6436 SET_INT(result, 5, ru->ru_isrss);
6437 SET_INT(result, 6, ru->ru_minflt);
6438 SET_INT(result, 7, ru->ru_majflt);
6439 SET_INT(result, 8, ru->ru_nswap);
6440 SET_INT(result, 9, ru->ru_inblock);
6441 SET_INT(result, 10, ru->ru_oublock);
6442 SET_INT(result, 11, ru->ru_msgsnd);
6443 SET_INT(result, 12, ru->ru_msgrcv);
6444 SET_INT(result, 13, ru->ru_nsignals);
6445 SET_INT(result, 14, ru->ru_nvcsw);
6446 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006447#undef SET_INT
6448
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 if (PyErr_Occurred()) {
6450 Py_DECREF(result);
6451 return NULL;
6452 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006453
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006455}
6456#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6457
6458#ifdef HAVE_WAIT3
6459PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006460"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006461Wait for completion of a child process.");
6462
6463static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006464posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006465{
Victor Stinner8c62be82010-05-06 00:08:46 +00006466 pid_t pid;
6467 int options;
6468 struct rusage ru;
6469 WAIT_TYPE status;
6470 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006471
Victor Stinner4195b5c2012-02-08 23:03:19 +01006472 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006473 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006474
Victor Stinner8c62be82010-05-06 00:08:46 +00006475 Py_BEGIN_ALLOW_THREADS
6476 pid = wait3(&status, options, &ru);
6477 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006478
Victor Stinner4195b5c2012-02-08 23:03:19 +01006479 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006480}
6481#endif /* HAVE_WAIT3 */
6482
6483#ifdef HAVE_WAIT4
6484PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006485"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006486Wait for completion of a given child process.");
6487
6488static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006489posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006490{
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 pid_t pid;
6492 int options;
6493 struct rusage ru;
6494 WAIT_TYPE status;
6495 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006496
Victor Stinner4195b5c2012-02-08 23:03:19 +01006497 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006498 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006499
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 Py_BEGIN_ALLOW_THREADS
6501 pid = wait4(pid, &status, options, &ru);
6502 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006503
Victor Stinner4195b5c2012-02-08 23:03:19 +01006504 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006505}
6506#endif /* HAVE_WAIT4 */
6507
Ross Lagerwall7807c352011-03-17 20:20:30 +02006508#if defined(HAVE_WAITID) && !defined(__APPLE__)
6509PyDoc_STRVAR(posix_waitid__doc__,
6510"waitid(idtype, id, options) -> waitid_result\n\n\
6511Wait for the completion of one or more child processes.\n\n\
6512idtype can be P_PID, P_PGID or P_ALL.\n\
6513id specifies the pid to wait on.\n\
6514options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6515or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6516Returns either waitid_result or None if WNOHANG is specified and there are\n\
6517no children in a waitable state.");
6518
6519static PyObject *
6520posix_waitid(PyObject *self, PyObject *args)
6521{
6522 PyObject *result;
6523 idtype_t idtype;
6524 id_t id;
6525 int options, res;
6526 siginfo_t si;
6527 si.si_pid = 0;
6528 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6529 return NULL;
6530 Py_BEGIN_ALLOW_THREADS
6531 res = waitid(idtype, id, &si, options);
6532 Py_END_ALLOW_THREADS
6533 if (res == -1)
6534 return posix_error();
6535
6536 if (si.si_pid == 0)
6537 Py_RETURN_NONE;
6538
6539 result = PyStructSequence_New(&WaitidResultType);
6540 if (!result)
6541 return NULL;
6542
6543 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006544 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006545 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6546 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6547 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6548 if (PyErr_Occurred()) {
6549 Py_DECREF(result);
6550 return NULL;
6551 }
6552
6553 return result;
6554}
6555#endif
6556
Guido van Rossumb6775db1994-08-01 11:34:53 +00006557#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006558PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006559"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006560Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006561
Barry Warsaw53699e91996-12-10 23:23:01 +00006562static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006563posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006564{
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 pid_t pid;
6566 int options;
6567 WAIT_TYPE status;
6568 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006569
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6571 return NULL;
6572 Py_BEGIN_ALLOW_THREADS
6573 pid = waitpid(pid, &status, options);
6574 Py_END_ALLOW_THREADS
6575 if (pid == -1)
6576 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006577
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006579}
6580
Tim Petersab034fa2002-02-01 11:27:43 +00006581#elif defined(HAVE_CWAIT)
6582
6583/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006584PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006585"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006586"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006587
6588static PyObject *
6589posix_waitpid(PyObject *self, PyObject *args)
6590{
Victor Stinner8c62be82010-05-06 00:08:46 +00006591 Py_intptr_t pid;
6592 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006593
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6595 return NULL;
6596 Py_BEGIN_ALLOW_THREADS
6597 pid = _cwait(&status, pid, options);
6598 Py_END_ALLOW_THREADS
6599 if (pid == -1)
6600 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006601
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 /* shift the status left a byte so this is more like the POSIX waitpid */
6603 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006604}
6605#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006606
Guido van Rossumad0ee831995-03-01 10:34:45 +00006607#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006608PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006609"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006610Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006611
Barry Warsaw53699e91996-12-10 23:23:01 +00006612static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006613posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006614{
Victor Stinner8c62be82010-05-06 00:08:46 +00006615 pid_t pid;
6616 WAIT_TYPE status;
6617 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006618
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 Py_BEGIN_ALLOW_THREADS
6620 pid = wait(&status);
6621 Py_END_ALLOW_THREADS
6622 if (pid == -1)
6623 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006624
Victor Stinner8c62be82010-05-06 00:08:46 +00006625 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006626}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006627#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006628
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006629
Larry Hastings9cf065c2012-06-22 16:30:09 -07006630#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6631PyDoc_STRVAR(readlink__doc__,
6632"readlink(path, *, dir_fd=None) -> path\n\n\
6633Return a string representing the path to which the symbolic link points.\n\
6634\n\
6635If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6636 and path should be relative; path will then be relative to that directory.\n\
6637dir_fd may not be implemented on your platform.\n\
6638 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006639#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006640
Guido van Rossumb6775db1994-08-01 11:34:53 +00006641#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006642
Barry Warsaw53699e91996-12-10 23:23:01 +00006643static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006644posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006645{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006646 path_t path;
6647 int dir_fd = DEFAULT_DIR_FD;
6648 char buffer[MAXPATHLEN];
6649 ssize_t length;
6650 PyObject *return_value = NULL;
6651 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006652
Larry Hastings9cf065c2012-06-22 16:30:09 -07006653 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006654 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006655 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6656 path_converter, &path,
6657#ifdef HAVE_READLINKAT
6658 dir_fd_converter, &dir_fd
6659#else
6660 dir_fd_unavailable, &dir_fd
6661#endif
6662 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00006663 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006664
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006666#ifdef HAVE_READLINKAT
6667 if (dir_fd != DEFAULT_DIR_FD)
6668 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006669 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006670#endif
6671 length = readlink(path.narrow, buffer, sizeof(buffer));
6672 Py_END_ALLOW_THREADS
6673
6674 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006675 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006676 goto exit;
6677 }
6678
6679 if (PyUnicode_Check(path.object))
6680 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6681 else
6682 return_value = PyBytes_FromStringAndSize(buffer, length);
6683exit:
6684 path_cleanup(&path);
6685 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006686}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006687
6688
Guido van Rossumb6775db1994-08-01 11:34:53 +00006689#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006691
Larry Hastings9cf065c2012-06-22 16:30:09 -07006692#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006693PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07006694"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
6695Create a symbolic link pointing to src named dst.\n\n\
6696target_is_directory is required on Windows if the target is to be\n\
6697 interpreted as a directory. (On Windows, symlink requires\n\
6698 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
6699 target_is_directory is ignored on non-Windows platforms.\n\
6700\n\
6701If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6702 and path should be relative; path will then be relative to that directory.\n\
6703dir_fd may not be implemented on your platform.\n\
6704 If it is unavailable, using it will raise a NotImplementedError.");
6705
6706#if defined(MS_WINDOWS)
6707
6708/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6709static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
6710static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
6711static int
6712check_CreateSymbolicLink()
6713{
6714 HINSTANCE hKernel32;
6715 /* only recheck */
6716 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
6717 return 1;
6718 hKernel32 = GetModuleHandleW(L"KERNEL32");
6719 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6720 "CreateSymbolicLinkW");
6721 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
6722 "CreateSymbolicLinkA");
6723 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
6724}
6725
6726#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006727
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006728static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006729posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006730{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006731 path_t src;
6732 path_t dst;
6733 int dir_fd = DEFAULT_DIR_FD;
6734 int target_is_directory = 0;
6735 static char *keywords[] = {"src", "dst", "target_is_directory",
6736 "dir_fd", NULL};
6737 PyObject *return_value;
6738#ifdef MS_WINDOWS
6739 DWORD result;
6740#else
6741 int result;
6742#endif
6743
6744 memset(&src, 0, sizeof(src));
Victor Stinner292c8352012-10-30 02:17:38 +01006745 src.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006746 src.argument_name = "src";
6747 memset(&dst, 0, sizeof(dst));
Victor Stinner292c8352012-10-30 02:17:38 +01006748 dst.function_name = "symlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006749 dst.argument_name = "dst";
6750
6751#ifdef MS_WINDOWS
6752 if (!check_CreateSymbolicLink()) {
6753 PyErr_SetString(PyExc_NotImplementedError,
6754 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006755 return NULL;
6756 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006757 if (!win32_can_symlink) {
6758 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006759 return NULL;
6760 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07006761#endif
6762
6763 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
6764 keywords,
6765 path_converter, &src,
6766 path_converter, &dst,
6767 &target_is_directory,
6768#ifdef HAVE_SYMLINKAT
6769 dir_fd_converter, &dir_fd
6770#else
6771 dir_fd_unavailable, &dir_fd
6772#endif
6773 ))
6774 return NULL;
6775
6776 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
6777 PyErr_SetString(PyExc_ValueError,
6778 "symlink: src and dst must be the same type");
6779 return_value = NULL;
6780 goto exit;
6781 }
6782
6783#ifdef MS_WINDOWS
6784 Py_BEGIN_ALLOW_THREADS
6785 if (dst.wide)
6786 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
6787 target_is_directory);
6788 else
6789 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
6790 target_is_directory);
6791 Py_END_ALLOW_THREADS
6792
6793 if (!result) {
Victor Stinnerb024e842012-10-31 22:24:06 +01006794 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006795 goto exit;
6796 }
6797
6798#else
6799
6800 Py_BEGIN_ALLOW_THREADS
6801#if HAVE_SYMLINKAT
6802 if (dir_fd != DEFAULT_DIR_FD)
6803 result = symlinkat(src.narrow, dir_fd, dst.narrow);
6804 else
6805#endif
6806 result = symlink(src.narrow, dst.narrow);
6807 Py_END_ALLOW_THREADS
6808
6809 if (result) {
Victor Stinnerafe17062012-10-31 22:47:43 +01006810 return_value = path_error(&src);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006811 goto exit;
6812 }
6813#endif
6814
6815 return_value = Py_None;
6816 Py_INCREF(Py_None);
6817 goto exit; /* silence "unused label" warning */
6818exit:
6819 path_cleanup(&src);
6820 path_cleanup(&dst);
6821 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006822}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006823
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006824#endif /* HAVE_SYMLINK */
6825
Larry Hastings9cf065c2012-06-22 16:30:09 -07006826
Brian Curtind40e6f72010-07-08 21:39:08 +00006827#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6828
Brian Curtind40e6f72010-07-08 21:39:08 +00006829static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006830win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00006831{
6832 wchar_t *path;
6833 DWORD n_bytes_returned;
6834 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006835 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03006836 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00006837 HANDLE reparse_point_handle;
6838
6839 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6840 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6841 wchar_t *print_name;
6842
Larry Hastings9cf065c2012-06-22 16:30:09 -07006843 static char *keywords[] = {"path", "dir_fd", NULL};
6844
6845 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
6846 &po,
6847 dir_fd_unavailable, &dir_fd
6848 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02006849 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07006850
Victor Stinnereb5657a2011-09-30 01:44:27 +02006851 path = PyUnicode_AsUnicode(po);
6852 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006853 return NULL;
6854
6855 /* First get a handle to the reparse point */
6856 Py_BEGIN_ALLOW_THREADS
6857 reparse_point_handle = CreateFileW(
6858 path,
6859 0,
6860 0,
6861 0,
6862 OPEN_EXISTING,
6863 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6864 0);
6865 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006866
Brian Curtind40e6f72010-07-08 21:39:08 +00006867 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006868 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006869
Brian Curtind40e6f72010-07-08 21:39:08 +00006870 Py_BEGIN_ALLOW_THREADS
6871 /* New call DeviceIoControl to read the reparse point */
6872 io_result = DeviceIoControl(
6873 reparse_point_handle,
6874 FSCTL_GET_REPARSE_POINT,
6875 0, 0, /* in buffer */
6876 target_buffer, sizeof(target_buffer),
6877 &n_bytes_returned,
6878 0 /* we're not using OVERLAPPED_IO */
6879 );
6880 CloseHandle(reparse_point_handle);
6881 Py_END_ALLOW_THREADS
6882
6883 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006884 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006885
6886 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6887 {
6888 PyErr_SetString(PyExc_ValueError,
6889 "not a symbolic link");
6890 return NULL;
6891 }
Brian Curtin74e45612010-07-09 15:58:59 +00006892 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6893 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6894
6895 result = PyUnicode_FromWideChar(print_name,
6896 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006897 return result;
6898}
6899
6900#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6901
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006902
Larry Hastings605a62d2012-06-24 04:33:36 -07006903static PyStructSequence_Field times_result_fields[] = {
6904 {"user", "user time"},
6905 {"system", "system time"},
6906 {"children_user", "user time of children"},
6907 {"children_system", "system time of children"},
6908 {"elapsed", "elapsed time since an arbitrary point in the past"},
6909 {NULL}
6910};
6911
6912PyDoc_STRVAR(times_result__doc__,
6913"times_result: Result from os.times().\n\n\
6914This object may be accessed either as a tuple of\n\
6915 (user, system, children_user, children_system, elapsed),\n\
6916or via the attributes user, system, children_user, children_system,\n\
6917and elapsed.\n\
6918\n\
6919See os.times for more information.");
6920
6921static PyStructSequence_Desc times_result_desc = {
6922 "times_result", /* name */
6923 times_result__doc__, /* doc */
6924 times_result_fields,
6925 5
6926};
6927
6928static PyTypeObject TimesResultType;
6929
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006930#ifdef MS_WINDOWS
6931#define HAVE_TIMES /* mandatory, for the method table */
6932#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07006933
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006934#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07006935
6936static PyObject *
6937build_times_result(double user, double system,
6938 double children_user, double children_system,
6939 double elapsed)
6940{
6941 PyObject *value = PyStructSequence_New(&TimesResultType);
6942 if (value == NULL)
6943 return NULL;
6944
6945#define SET(i, field) \
6946 { \
6947 PyObject *o = PyFloat_FromDouble(field); \
6948 if (!o) { \
6949 Py_DECREF(value); \
6950 return NULL; \
6951 } \
6952 PyStructSequence_SET_ITEM(value, i, o); \
6953 } \
6954
6955 SET(0, user);
6956 SET(1, system);
6957 SET(2, children_user);
6958 SET(3, children_system);
6959 SET(4, elapsed);
6960
6961#undef SET
6962
6963 return value;
6964}
6965
6966PyDoc_STRVAR(posix_times__doc__,
6967"times() -> times_result\n\n\
6968Return an object containing floating point numbers indicating process\n\
6969times. The object behaves like a named tuple with these fields:\n\
6970 (utime, stime, cutime, cstime, elapsed_time)");
6971
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006972#if defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00006973static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006974posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006975{
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 FILETIME create, exit, kernel, user;
6977 HANDLE hProc;
6978 hProc = GetCurrentProcess();
6979 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6980 /* The fields of a FILETIME structure are the hi and lo part
6981 of a 64-bit value expressed in 100 nanosecond units.
6982 1e7 is one second in such units; 1e-7 the inverse.
6983 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6984 */
Larry Hastings605a62d2012-06-24 04:33:36 -07006985 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 (double)(user.dwHighDateTime*429.4967296 +
6987 user.dwLowDateTime*1e-7),
6988 (double)(kernel.dwHighDateTime*429.4967296 +
6989 kernel.dwLowDateTime*1e-7),
6990 (double)0,
6991 (double)0,
6992 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006993}
Jesus Ceaab70e2a2012-10-05 01:48:08 +02006994#else /* Not Windows */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02006995#define NEED_TICKS_PER_SECOND
6996static long ticks_per_second = -1;
6997static PyObject *
6998posix_times(PyObject *self, PyObject *noargs)
6999{
7000 struct tms t;
7001 clock_t c;
7002 errno = 0;
7003 c = times(&t);
7004 if (c == (clock_t) -1)
7005 return posix_error();
7006 return build_times_result(
7007 (double)t.tms_utime / ticks_per_second,
7008 (double)t.tms_stime / ticks_per_second,
7009 (double)t.tms_cutime / ticks_per_second,
7010 (double)t.tms_cstime / ticks_per_second,
7011 (double)c / ticks_per_second);
7012}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007013#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007014
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007015#endif /* HAVE_TIMES */
7016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007017
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007018#ifdef HAVE_GETSID
7019PyDoc_STRVAR(posix_getsid__doc__,
7020"getsid(pid) -> sid\n\n\
7021Call the system call getsid().");
7022
7023static PyObject *
7024posix_getsid(PyObject *self, PyObject *args)
7025{
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 pid_t pid;
7027 int sid;
7028 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7029 return NULL;
7030 sid = getsid(pid);
7031 if (sid < 0)
7032 return posix_error();
7033 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007034}
7035#endif /* HAVE_GETSID */
7036
7037
Guido van Rossumb6775db1994-08-01 11:34:53 +00007038#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007039PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007040"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007041Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007042
Barry Warsaw53699e91996-12-10 23:23:01 +00007043static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007044posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007045{
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 if (setsid() < 0)
7047 return posix_error();
7048 Py_INCREF(Py_None);
7049 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007050}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007051#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007052
Guido van Rossumb6775db1994-08-01 11:34:53 +00007053#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007054PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007055"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007056Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007057
Barry Warsaw53699e91996-12-10 23:23:01 +00007058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007059posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007060{
Victor Stinner8c62be82010-05-06 00:08:46 +00007061 pid_t pid;
7062 int pgrp;
7063 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7064 return NULL;
7065 if (setpgid(pid, pgrp) < 0)
7066 return posix_error();
7067 Py_INCREF(Py_None);
7068 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007069}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007070#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007071
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007072
Guido van Rossumb6775db1994-08-01 11:34:53 +00007073#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007074PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007075"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007076Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007077
Barry Warsaw53699e91996-12-10 23:23:01 +00007078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007079posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007080{
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 int fd;
7082 pid_t pgid;
7083 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7084 return NULL;
7085 pgid = tcgetpgrp(fd);
7086 if (pgid < 0)
7087 return posix_error();
7088 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007089}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007090#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007091
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007092
Guido van Rossumb6775db1994-08-01 11:34:53 +00007093#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007094PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007095"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007096Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007097
Barry Warsaw53699e91996-12-10 23:23:01 +00007098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007099posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007100{
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 int fd;
7102 pid_t pgid;
7103 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7104 return NULL;
7105 if (tcsetpgrp(fd, pgid) < 0)
7106 return posix_error();
7107 Py_INCREF(Py_None);
7108 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007109}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007110#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007111
Guido van Rossum687dd131993-05-17 08:34:16 +00007112/* Functions acting on file descriptors */
7113
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007114PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007115"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7116Open a file for low level IO. Returns a file handle (integer).\n\
7117\n\
7118If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7119 and path should be relative; path will then be relative to that directory.\n\
7120dir_fd may not be implemented on your platform.\n\
7121 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007122
Barry Warsaw53699e91996-12-10 23:23:01 +00007123static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007125{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126 path_t path;
7127 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007128 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007129 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007130 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131 PyObject *return_value = NULL;
7132 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007133
Larry Hastings9cf065c2012-06-22 16:30:09 -07007134 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007135 path.function_name = "open";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007136 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7137 path_converter, &path,
7138 &flags, &mode,
7139#ifdef HAVE_OPENAT
7140 dir_fd_converter, &dir_fd
7141#else
7142 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007143#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007144 ))
7145 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007146
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007148#ifdef MS_WINDOWS
7149 if (path.wide)
7150 fd = _wopen(path.wide, flags, mode);
7151 else
7152#endif
7153#ifdef HAVE_OPENAT
7154 if (dir_fd != DEFAULT_DIR_FD)
7155 fd = openat(dir_fd, path.narrow, flags, mode);
7156 else
7157#endif
7158 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007160
Larry Hastings9cf065c2012-06-22 16:30:09 -07007161 if (fd == -1) {
Victor Stinner4e7d2d42012-11-05 01:20:58 +01007162 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007163 goto exit;
7164 }
7165
7166 return_value = PyLong_FromLong((long)fd);
7167
7168exit:
7169 path_cleanup(&path);
7170 return return_value;
7171}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007172
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007173PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007174"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007175Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007176
Barry Warsaw53699e91996-12-10 23:23:01 +00007177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007178posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007179{
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 int fd, res;
7181 if (!PyArg_ParseTuple(args, "i:close", &fd))
7182 return NULL;
7183 if (!_PyVerify_fd(fd))
7184 return posix_error();
7185 Py_BEGIN_ALLOW_THREADS
7186 res = close(fd);
7187 Py_END_ALLOW_THREADS
7188 if (res < 0)
7189 return posix_error();
7190 Py_INCREF(Py_None);
7191 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007192}
7193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007194
Victor Stinner8c62be82010-05-06 00:08:46 +00007195PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007196"closerange(fd_low, fd_high)\n\n\
7197Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7198
7199static PyObject *
7200posix_closerange(PyObject *self, PyObject *args)
7201{
Victor Stinner8c62be82010-05-06 00:08:46 +00007202 int fd_from, fd_to, i;
7203 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7204 return NULL;
7205 Py_BEGIN_ALLOW_THREADS
7206 for (i = fd_from; i < fd_to; i++)
7207 if (_PyVerify_fd(i))
7208 close(i);
7209 Py_END_ALLOW_THREADS
7210 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007211}
7212
7213
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007214PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007215"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007216Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007217
Barry Warsaw53699e91996-12-10 23:23:01 +00007218static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007219posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007220{
Victor Stinner8c62be82010-05-06 00:08:46 +00007221 int fd;
7222 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7223 return NULL;
7224 if (!_PyVerify_fd(fd))
7225 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007226 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007227 if (fd < 0)
7228 return posix_error();
7229 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007230}
7231
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007232
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007233PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007234"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007235Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007236
Barry Warsaw53699e91996-12-10 23:23:01 +00007237static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007238posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007239{
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 int fd, fd2, res;
7241 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7242 return NULL;
7243 if (!_PyVerify_fd_dup2(fd, fd2))
7244 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007245 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 if (res < 0)
7247 return posix_error();
7248 Py_INCREF(Py_None);
7249 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007250}
7251
Ross Lagerwall7807c352011-03-17 20:20:30 +02007252#ifdef HAVE_LOCKF
7253PyDoc_STRVAR(posix_lockf__doc__,
7254"lockf(fd, cmd, len)\n\n\
7255Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7256fd is an open file descriptor.\n\
7257cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7258F_TEST.\n\
7259len specifies the section of the file to lock.");
7260
7261static PyObject *
7262posix_lockf(PyObject *self, PyObject *args)
7263{
7264 int fd, cmd, res;
7265 off_t len;
7266 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7267 &fd, &cmd, _parse_off_t, &len))
7268 return NULL;
7269
7270 Py_BEGIN_ALLOW_THREADS
7271 res = lockf(fd, cmd, len);
7272 Py_END_ALLOW_THREADS
7273
7274 if (res < 0)
7275 return posix_error();
7276
7277 Py_RETURN_NONE;
7278}
7279#endif
7280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007281
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007282PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007283"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007284Set the current position of a file descriptor.\n\
7285Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007286
Barry Warsaw53699e91996-12-10 23:23:01 +00007287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007288posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007289{
Victor Stinner8c62be82010-05-06 00:08:46 +00007290 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007291#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007292 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007293#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007294 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007295#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007296 PyObject *posobj;
7297 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007298 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007299#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007300 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7301 switch (how) {
7302 case 0: how = SEEK_SET; break;
7303 case 1: how = SEEK_CUR; break;
7304 case 2: how = SEEK_END; break;
7305 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007306#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007307
Ross Lagerwall8e749672011-03-17 21:54:07 +02007308#if !defined(HAVE_LARGEFILE_SUPPORT)
7309 pos = PyLong_AsLong(posobj);
7310#else
7311 pos = PyLong_AsLongLong(posobj);
7312#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007313 if (PyErr_Occurred())
7314 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007315
Victor Stinner8c62be82010-05-06 00:08:46 +00007316 if (!_PyVerify_fd(fd))
7317 return posix_error();
7318 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007319#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007320 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007321#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007322 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007323#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007324 Py_END_ALLOW_THREADS
7325 if (res < 0)
7326 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007327
7328#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007329 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007330#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007331 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007332#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007333}
7334
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007335
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007336PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007337"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007338Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007339
Barry Warsaw53699e91996-12-10 23:23:01 +00007340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007341posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007342{
Victor Stinner8c62be82010-05-06 00:08:46 +00007343 int fd, size;
7344 Py_ssize_t n;
7345 PyObject *buffer;
7346 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7347 return NULL;
7348 if (size < 0) {
7349 errno = EINVAL;
7350 return posix_error();
7351 }
7352 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7353 if (buffer == NULL)
7354 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007355 if (!_PyVerify_fd(fd)) {
7356 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007357 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007358 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007359 Py_BEGIN_ALLOW_THREADS
7360 n = read(fd, PyBytes_AS_STRING(buffer), size);
7361 Py_END_ALLOW_THREADS
7362 if (n < 0) {
7363 Py_DECREF(buffer);
7364 return posix_error();
7365 }
7366 if (n != size)
7367 _PyBytes_Resize(&buffer, n);
7368 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007369}
7370
Ross Lagerwall7807c352011-03-17 20:20:30 +02007371#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7372 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007373static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007374iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7375{
7376 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007377 Py_ssize_t blen, total = 0;
7378
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007379 *iov = PyMem_New(struct iovec, cnt);
7380 if (*iov == NULL) {
7381 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007382 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007383 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007384
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007385 *buf = PyMem_New(Py_buffer, cnt);
7386 if (*buf == NULL) {
7387 PyMem_Del(*iov);
7388 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007389 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007390 }
7391
7392 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007393 PyObject *item = PySequence_GetItem(seq, i);
7394 if (item == NULL)
7395 goto fail;
7396 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7397 Py_DECREF(item);
7398 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007399 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007400 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007401 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007402 blen = (*buf)[i].len;
7403 (*iov)[i].iov_len = blen;
7404 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007405 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007406 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007407
7408fail:
7409 PyMem_Del(*iov);
7410 for (j = 0; j < i; j++) {
7411 PyBuffer_Release(&(*buf)[j]);
7412 }
7413 PyMem_Del(*buf);
7414 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007415}
7416
7417static void
7418iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7419{
7420 int i;
7421 PyMem_Del(iov);
7422 for (i = 0; i < cnt; i++) {
7423 PyBuffer_Release(&buf[i]);
7424 }
7425 PyMem_Del(buf);
7426}
7427#endif
7428
Ross Lagerwall7807c352011-03-17 20:20:30 +02007429#ifdef HAVE_READV
7430PyDoc_STRVAR(posix_readv__doc__,
7431"readv(fd, buffers) -> bytesread\n\n\
7432Read from a file descriptor into a number of writable buffers. buffers\n\
7433is an arbitrary sequence of writable buffers.\n\
7434Returns the total number of bytes read.");
7435
7436static PyObject *
7437posix_readv(PyObject *self, PyObject *args)
7438{
7439 int fd, cnt;
7440 Py_ssize_t n;
7441 PyObject *seq;
7442 struct iovec *iov;
7443 Py_buffer *buf;
7444
7445 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7446 return NULL;
7447 if (!PySequence_Check(seq)) {
7448 PyErr_SetString(PyExc_TypeError,
7449 "readv() arg 2 must be a sequence");
7450 return NULL;
7451 }
7452 cnt = PySequence_Size(seq);
7453
7454 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7455 return NULL;
7456
7457 Py_BEGIN_ALLOW_THREADS
7458 n = readv(fd, iov, cnt);
7459 Py_END_ALLOW_THREADS
7460
7461 iov_cleanup(iov, buf, cnt);
7462 return PyLong_FromSsize_t(n);
7463}
7464#endif
7465
7466#ifdef HAVE_PREAD
7467PyDoc_STRVAR(posix_pread__doc__,
7468"pread(fd, buffersize, offset) -> string\n\n\
7469Read from a file descriptor, fd, at a position of offset. It will read up\n\
7470to buffersize number of bytes. The file offset remains unchanged.");
7471
7472static PyObject *
7473posix_pread(PyObject *self, PyObject *args)
7474{
7475 int fd, size;
7476 off_t offset;
7477 Py_ssize_t n;
7478 PyObject *buffer;
7479 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7480 return NULL;
7481
7482 if (size < 0) {
7483 errno = EINVAL;
7484 return posix_error();
7485 }
7486 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7487 if (buffer == NULL)
7488 return NULL;
7489 if (!_PyVerify_fd(fd)) {
7490 Py_DECREF(buffer);
7491 return posix_error();
7492 }
7493 Py_BEGIN_ALLOW_THREADS
7494 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7495 Py_END_ALLOW_THREADS
7496 if (n < 0) {
7497 Py_DECREF(buffer);
7498 return posix_error();
7499 }
7500 if (n != size)
7501 _PyBytes_Resize(&buffer, n);
7502 return buffer;
7503}
7504#endif
7505
7506PyDoc_STRVAR(posix_write__doc__,
7507"write(fd, string) -> byteswritten\n\n\
7508Write a string to a file descriptor.");
7509
7510static PyObject *
7511posix_write(PyObject *self, PyObject *args)
7512{
7513 Py_buffer pbuf;
7514 int fd;
7515 Py_ssize_t size, len;
7516
7517 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7518 return NULL;
7519 if (!_PyVerify_fd(fd)) {
7520 PyBuffer_Release(&pbuf);
7521 return posix_error();
7522 }
7523 len = pbuf.len;
7524 Py_BEGIN_ALLOW_THREADS
7525#if defined(MS_WIN64) || defined(MS_WINDOWS)
7526 if (len > INT_MAX)
7527 len = INT_MAX;
7528 size = write(fd, pbuf.buf, (int)len);
7529#else
7530 size = write(fd, pbuf.buf, len);
7531#endif
7532 Py_END_ALLOW_THREADS
7533 PyBuffer_Release(&pbuf);
7534 if (size < 0)
7535 return posix_error();
7536 return PyLong_FromSsize_t(size);
7537}
7538
7539#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007540PyDoc_STRVAR(posix_sendfile__doc__,
7541"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7542sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7543 -> byteswritten\n\
7544Copy nbytes bytes from file descriptor in to file descriptor out.");
7545
7546static PyObject *
7547posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7548{
7549 int in, out;
7550 Py_ssize_t ret;
7551 off_t offset;
7552
7553#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7554#ifndef __APPLE__
7555 Py_ssize_t len;
7556#endif
7557 PyObject *headers = NULL, *trailers = NULL;
7558 Py_buffer *hbuf, *tbuf;
7559 off_t sbytes;
7560 struct sf_hdtr sf;
7561 int flags = 0;
7562 sf.headers = NULL;
7563 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007564 static char *keywords[] = {"out", "in",
7565 "offset", "count",
7566 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007567
7568#ifdef __APPLE__
7569 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007570 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007571#else
7572 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007573 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007574#endif
7575 &headers, &trailers, &flags))
7576 return NULL;
7577 if (headers != NULL) {
7578 if (!PySequence_Check(headers)) {
7579 PyErr_SetString(PyExc_TypeError,
7580 "sendfile() headers must be a sequence or None");
7581 return NULL;
7582 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007583 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007584 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007585 if (sf.hdr_cnt > 0 &&
7586 !(i = iov_setup(&(sf.headers), &hbuf,
7587 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007588 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007589#ifdef __APPLE__
7590 sbytes += i;
7591#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007592 }
7593 }
7594 if (trailers != NULL) {
7595 if (!PySequence_Check(trailers)) {
7596 PyErr_SetString(PyExc_TypeError,
7597 "sendfile() trailers must be a sequence or None");
7598 return NULL;
7599 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007600 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007601 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007602 if (sf.trl_cnt > 0 &&
7603 !(i = iov_setup(&(sf.trailers), &tbuf,
7604 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007605 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007606#ifdef __APPLE__
7607 sbytes += i;
7608#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007609 }
7610 }
7611
7612 Py_BEGIN_ALLOW_THREADS
7613#ifdef __APPLE__
7614 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7615#else
7616 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7617#endif
7618 Py_END_ALLOW_THREADS
7619
7620 if (sf.headers != NULL)
7621 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7622 if (sf.trailers != NULL)
7623 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7624
7625 if (ret < 0) {
7626 if ((errno == EAGAIN) || (errno == EBUSY)) {
7627 if (sbytes != 0) {
7628 // some data has been sent
7629 goto done;
7630 }
7631 else {
7632 // no data has been sent; upper application is supposed
7633 // to retry on EAGAIN or EBUSY
7634 return posix_error();
7635 }
7636 }
7637 return posix_error();
7638 }
7639 goto done;
7640
7641done:
7642 #if !defined(HAVE_LARGEFILE_SUPPORT)
7643 return Py_BuildValue("l", sbytes);
7644 #else
7645 return Py_BuildValue("L", sbytes);
7646 #endif
7647
7648#else
7649 Py_ssize_t count;
7650 PyObject *offobj;
7651 static char *keywords[] = {"out", "in",
7652 "offset", "count", NULL};
7653 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7654 keywords, &out, &in, &offobj, &count))
7655 return NULL;
7656#ifdef linux
7657 if (offobj == Py_None) {
7658 Py_BEGIN_ALLOW_THREADS
7659 ret = sendfile(out, in, NULL, count);
7660 Py_END_ALLOW_THREADS
7661 if (ret < 0)
7662 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007663 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007664 }
7665#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007666 if (!_parse_off_t(offobj, &offset))
7667 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007668 Py_BEGIN_ALLOW_THREADS
7669 ret = sendfile(out, in, &offset, count);
7670 Py_END_ALLOW_THREADS
7671 if (ret < 0)
7672 return posix_error();
7673 return Py_BuildValue("n", ret);
7674#endif
7675}
7676#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007677
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007678PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007679"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007680Like stat(), but for an open file descriptor.\n\
7681Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007682
Barry Warsaw53699e91996-12-10 23:23:01 +00007683static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007684posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007685{
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 int fd;
7687 STRUCT_STAT st;
7688 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01007689 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007690 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007691#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007692 /* on OpenVMS we must ensure that all bytes are written to the file */
7693 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007694#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 Py_BEGIN_ALLOW_THREADS
7696 res = FSTAT(fd, &st);
7697 Py_END_ALLOW_THREADS
7698 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007699#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01007700 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00007701#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007702 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007703#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007704 }
Tim Peters5aa91602002-01-30 05:46:57 +00007705
Victor Stinner4195b5c2012-02-08 23:03:19 +01007706 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007707}
7708
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007709PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007710"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007711Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007712connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007713
7714static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007715posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007716{
Victor Stinner8c62be82010-05-06 00:08:46 +00007717 int fd;
7718 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7719 return NULL;
7720 if (!_PyVerify_fd(fd))
7721 return PyBool_FromLong(0);
7722 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007723}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007724
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007725#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007726PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007727"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007728Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007729
Barry Warsaw53699e91996-12-10 23:23:01 +00007730static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007731posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007732{
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007733#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007734 int fds[2];
7735 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007736 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 if (res != 0)
7738 return posix_error();
7739 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007740#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007741 HANDLE read, write;
7742 int read_fd, write_fd;
7743 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007744 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01007746 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007747 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7748 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7749 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007750#endif /* MS_WINDOWS */
Guido van Rossum687dd131993-05-17 08:34:16 +00007751}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007752#endif /* HAVE_PIPE */
7753
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007754#ifdef HAVE_PIPE2
7755PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007756"pipe2(flags) -> (read_end, write_end)\n\n\
7757Create a pipe with flags set atomically.\n\
7758flags can be constructed by ORing together one or more of these values:\n\
7759O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007760");
7761
7762static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007763posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007764{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007765 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007766 int fds[2];
7767 int res;
7768
Serhiy Storchaka78980432013-01-15 01:12:17 +02007769 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02007770 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007771 return NULL;
7772
7773 res = pipe2(fds, flags);
7774 if (res != 0)
7775 return posix_error();
7776 return Py_BuildValue("(ii)", fds[0], fds[1]);
7777}
7778#endif /* HAVE_PIPE2 */
7779
Ross Lagerwall7807c352011-03-17 20:20:30 +02007780#ifdef HAVE_WRITEV
7781PyDoc_STRVAR(posix_writev__doc__,
7782"writev(fd, buffers) -> byteswritten\n\n\
7783Write the contents of buffers to a file descriptor, where buffers is an\n\
7784arbitrary sequence of buffers.\n\
7785Returns the total bytes written.");
7786
7787static PyObject *
7788posix_writev(PyObject *self, PyObject *args)
7789{
7790 int fd, cnt;
7791 Py_ssize_t res;
7792 PyObject *seq;
7793 struct iovec *iov;
7794 Py_buffer *buf;
7795 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7796 return NULL;
7797 if (!PySequence_Check(seq)) {
7798 PyErr_SetString(PyExc_TypeError,
7799 "writev() arg 2 must be a sequence");
7800 return NULL;
7801 }
7802 cnt = PySequence_Size(seq);
7803
7804 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7805 return NULL;
7806 }
7807
7808 Py_BEGIN_ALLOW_THREADS
7809 res = writev(fd, iov, cnt);
7810 Py_END_ALLOW_THREADS
7811
7812 iov_cleanup(iov, buf, cnt);
7813 return PyLong_FromSsize_t(res);
7814}
7815#endif
7816
7817#ifdef HAVE_PWRITE
7818PyDoc_STRVAR(posix_pwrite__doc__,
7819"pwrite(fd, string, offset) -> byteswritten\n\n\
7820Write string to a file descriptor, fd, from offset, leaving the file\n\
7821offset unchanged.");
7822
7823static PyObject *
7824posix_pwrite(PyObject *self, PyObject *args)
7825{
7826 Py_buffer pbuf;
7827 int fd;
7828 off_t offset;
7829 Py_ssize_t size;
7830
7831 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7832 return NULL;
7833
7834 if (!_PyVerify_fd(fd)) {
7835 PyBuffer_Release(&pbuf);
7836 return posix_error();
7837 }
7838 Py_BEGIN_ALLOW_THREADS
7839 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7840 Py_END_ALLOW_THREADS
7841 PyBuffer_Release(&pbuf);
7842 if (size < 0)
7843 return posix_error();
7844 return PyLong_FromSsize_t(size);
7845}
7846#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007847
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007848#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007849PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007850"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
7851Create a FIFO (a POSIX named pipe).\n\
7852\n\
7853If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7854 and path should be relative; path will then be relative to that directory.\n\
7855dir_fd may not be implemented on your platform.\n\
7856 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007857
Barry Warsaw53699e91996-12-10 23:23:01 +00007858static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007859posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007860{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007861 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007863 int dir_fd = DEFAULT_DIR_FD;
7864 int result;
7865 PyObject *return_value = NULL;
7866 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
7867
7868 memset(&path, 0, sizeof(path));
7869 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
7870 path_converter, &path,
7871 &mode,
7872#ifdef HAVE_MKFIFOAT
7873 dir_fd_converter, &dir_fd
7874#else
7875 dir_fd_unavailable, &dir_fd
7876#endif
7877 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007878 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007879
Victor Stinner8c62be82010-05-06 00:08:46 +00007880 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007881#ifdef HAVE_MKFIFOAT
7882 if (dir_fd != DEFAULT_DIR_FD)
7883 result = mkfifoat(dir_fd, path.narrow, mode);
7884 else
7885#endif
7886 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007887 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007888
7889 if (result < 0) {
7890 return_value = posix_error();
7891 goto exit;
7892 }
7893
7894 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007895 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007896
7897exit:
7898 path_cleanup(&path);
7899 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007900}
7901#endif
7902
Neal Norwitz11690112002-07-30 01:08:28 +00007903#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007904PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007905"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007906Create a filesystem node (file, device special file or named pipe)\n\
7907named filename. mode specifies both the permissions to use and the\n\
7908type of node to be created, being combined (bitwise OR) with one of\n\
7909S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007910device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07007911os.makedev()), otherwise it is ignored.\n\
7912\n\
7913If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7914 and path should be relative; path will then be relative to that directory.\n\
7915dir_fd may not be implemented on your platform.\n\
7916 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007917
7918
7919static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007920posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007921{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007922 path_t path;
7923 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007925 int dir_fd = DEFAULT_DIR_FD;
7926 int result;
7927 PyObject *return_value = NULL;
7928 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
7929
7930 memset(&path, 0, sizeof(path));
7931 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
7932 path_converter, &path,
7933 &mode, &device,
7934#ifdef HAVE_MKNODAT
7935 dir_fd_converter, &dir_fd
7936#else
7937 dir_fd_unavailable, &dir_fd
7938#endif
7939 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007941
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007943#ifdef HAVE_MKNODAT
7944 if (dir_fd != DEFAULT_DIR_FD)
7945 result = mknodat(dir_fd, path.narrow, mode, device);
7946 else
7947#endif
7948 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00007949 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007950
7951 if (result < 0) {
7952 return_value = posix_error();
7953 goto exit;
7954 }
7955
7956 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02007958
Larry Hastings9cf065c2012-06-22 16:30:09 -07007959exit:
7960 path_cleanup(&path);
7961 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007962}
7963#endif
7964
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007965#ifdef HAVE_DEVICE_MACROS
7966PyDoc_STRVAR(posix_major__doc__,
7967"major(device) -> major number\n\
7968Extracts a device major number from a raw device number.");
7969
7970static PyObject *
7971posix_major(PyObject *self, PyObject *args)
7972{
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 int device;
7974 if (!PyArg_ParseTuple(args, "i:major", &device))
7975 return NULL;
7976 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007977}
7978
7979PyDoc_STRVAR(posix_minor__doc__,
7980"minor(device) -> minor number\n\
7981Extracts a device minor number from a raw device number.");
7982
7983static PyObject *
7984posix_minor(PyObject *self, PyObject *args)
7985{
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 int device;
7987 if (!PyArg_ParseTuple(args, "i:minor", &device))
7988 return NULL;
7989 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007990}
7991
7992PyDoc_STRVAR(posix_makedev__doc__,
7993"makedev(major, minor) -> device number\n\
7994Composes a raw device number from the major and minor device numbers.");
7995
7996static PyObject *
7997posix_makedev(PyObject *self, PyObject *args)
7998{
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 int major, minor;
8000 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8001 return NULL;
8002 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008003}
8004#endif /* device macros */
8005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008006
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008007#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008008PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008009"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008010Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008011
Barry Warsaw53699e91996-12-10 23:23:01 +00008012static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008013posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008014{
Victor Stinner8c62be82010-05-06 00:08:46 +00008015 int fd;
8016 off_t length;
8017 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008018
Ross Lagerwall7807c352011-03-17 20:20:30 +02008019 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008020 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008021
Victor Stinner8c62be82010-05-06 00:08:46 +00008022 Py_BEGIN_ALLOW_THREADS
8023 res = ftruncate(fd, length);
8024 Py_END_ALLOW_THREADS
8025 if (res < 0)
8026 return posix_error();
8027 Py_INCREF(Py_None);
8028 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008029}
8030#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008031
Ross Lagerwall7807c352011-03-17 20:20:30 +02008032#ifdef HAVE_TRUNCATE
8033PyDoc_STRVAR(posix_truncate__doc__,
8034"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008035Truncate the file given by path to length bytes.\n\
8036On some platforms, path may also be specified as an open file descriptor.\n\
8037 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008038
8039static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008040posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008041{
Georg Brandl306336b2012-06-24 12:55:33 +02008042 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008043 off_t length;
8044 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008045 PyObject *result = NULL;
8046 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008047
Georg Brandl306336b2012-06-24 12:55:33 +02008048 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008049 path.function_name = "truncate";
Georg Brandl306336b2012-06-24 12:55:33 +02008050#ifdef HAVE_FTRUNCATE
8051 path.allow_fd = 1;
8052#endif
8053 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8054 path_converter, &path,
8055 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008056 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008057
8058 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008059#ifdef HAVE_FTRUNCATE
8060 if (path.fd != -1)
8061 res = ftruncate(path.fd, length);
8062 else
8063#endif
8064 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008065 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008066 if (res < 0)
Victor Stinner292c8352012-10-30 02:17:38 +01008067 result = path_error(&path);
Georg Brandl306336b2012-06-24 12:55:33 +02008068 else {
8069 Py_INCREF(Py_None);
8070 result = Py_None;
8071 }
8072 path_cleanup(&path);
8073 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008074}
8075#endif
8076
8077#ifdef HAVE_POSIX_FALLOCATE
8078PyDoc_STRVAR(posix_posix_fallocate__doc__,
8079"posix_fallocate(fd, offset, len)\n\n\
8080Ensures that enough disk space is allocated for the file specified by fd\n\
8081starting from offset and continuing for len bytes.");
8082
8083static PyObject *
8084posix_posix_fallocate(PyObject *self, PyObject *args)
8085{
8086 off_t len, offset;
8087 int res, fd;
8088
8089 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8090 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8091 return NULL;
8092
8093 Py_BEGIN_ALLOW_THREADS
8094 res = posix_fallocate(fd, offset, len);
8095 Py_END_ALLOW_THREADS
8096 if (res != 0) {
8097 errno = res;
8098 return posix_error();
8099 }
8100 Py_RETURN_NONE;
8101}
8102#endif
8103
8104#ifdef HAVE_POSIX_FADVISE
8105PyDoc_STRVAR(posix_posix_fadvise__doc__,
8106"posix_fadvise(fd, offset, len, advice)\n\n\
8107Announces an intention to access data in a specific pattern thus allowing\n\
8108the kernel to make optimizations.\n\
8109The advice applies to the region of the file specified by fd starting at\n\
8110offset and continuing for len bytes.\n\
8111advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8112POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8113POSIX_FADV_DONTNEED.");
8114
8115static PyObject *
8116posix_posix_fadvise(PyObject *self, PyObject *args)
8117{
8118 off_t len, offset;
8119 int res, fd, advice;
8120
8121 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8122 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8123 return NULL;
8124
8125 Py_BEGIN_ALLOW_THREADS
8126 res = posix_fadvise(fd, offset, len, advice);
8127 Py_END_ALLOW_THREADS
8128 if (res != 0) {
8129 errno = res;
8130 return posix_error();
8131 }
8132 Py_RETURN_NONE;
8133}
8134#endif
8135
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008136#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008137PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008138"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008139Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008140
Fred Drake762e2061999-08-26 17:23:54 +00008141/* Save putenv() parameters as values here, so we can collect them when they
8142 * get re-set with another call for the same key. */
8143static PyObject *posix_putenv_garbage;
8144
Tim Peters5aa91602002-01-30 05:46:57 +00008145static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008146posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008147{
Victor Stinner84ae1182010-05-06 22:05:07 +00008148 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008149#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008150 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008151 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008152
Victor Stinner8c62be82010-05-06 00:08:46 +00008153 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008154 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008155 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008156 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008157
Victor Stinner65170952011-11-22 22:16:17 +01008158 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008159 if (newstr == NULL) {
8160 PyErr_NoMemory();
8161 goto error;
8162 }
Victor Stinner65170952011-11-22 22:16:17 +01008163 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8164 PyErr_Format(PyExc_ValueError,
8165 "the environment variable is longer than %u characters",
8166 _MAX_ENV);
8167 goto error;
8168 }
8169
Victor Stinner8c62be82010-05-06 00:08:46 +00008170 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008171 if (newenv == NULL)
8172 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008173 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008174 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008175 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008176 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008177#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008178 PyObject *os1, *os2;
8179 char *s1, *s2;
8180 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008181
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008182 if (!PyArg_ParseTuple(args,
8183 "O&O&:putenv",
8184 PyUnicode_FSConverter, &os1,
8185 PyUnicode_FSConverter, &os2))
8186 return NULL;
8187 s1 = PyBytes_AsString(os1);
8188 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008189
Victor Stinner65170952011-11-22 22:16:17 +01008190 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008191 if (newstr == NULL) {
8192 PyErr_NoMemory();
8193 goto error;
8194 }
8195
Victor Stinner8c62be82010-05-06 00:08:46 +00008196 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008197 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008198 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008199 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008200 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008201#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008202
Victor Stinner8c62be82010-05-06 00:08:46 +00008203 /* Install the first arg and newstr in posix_putenv_garbage;
8204 * this will cause previous value to be collected. This has to
8205 * happen after the real putenv() call because the old value
8206 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008207 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 /* really not much we can do; just leak */
8209 PyErr_Clear();
8210 }
8211 else {
8212 Py_DECREF(newstr);
8213 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008214
Martin v. Löwis011e8422009-05-05 04:43:17 +00008215#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008216 Py_DECREF(os1);
8217 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008218#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008219 Py_RETURN_NONE;
8220
8221error:
8222#ifndef MS_WINDOWS
8223 Py_DECREF(os1);
8224 Py_DECREF(os2);
8225#endif
8226 Py_XDECREF(newstr);
8227 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008228}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008229#endif /* putenv */
8230
Guido van Rossumc524d952001-10-19 01:31:59 +00008231#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008232PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008233"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008234Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008235
8236static PyObject *
8237posix_unsetenv(PyObject *self, PyObject *args)
8238{
Victor Stinner65170952011-11-22 22:16:17 +01008239 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008240#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008241 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008242#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008243
8244 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008245
Victor Stinner65170952011-11-22 22:16:17 +01008246 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008247 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008248
Victor Stinner984890f2011-11-24 13:53:38 +01008249#ifdef HAVE_BROKEN_UNSETENV
8250 unsetenv(PyBytes_AS_STRING(name));
8251#else
Victor Stinner65170952011-11-22 22:16:17 +01008252 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008253 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008254 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008255 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008256 }
Victor Stinner984890f2011-11-24 13:53:38 +01008257#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008258
Victor Stinner8c62be82010-05-06 00:08:46 +00008259 /* Remove the key from posix_putenv_garbage;
8260 * this will cause it to be collected. This has to
8261 * happen after the real unsetenv() call because the
8262 * old value was still accessible until then.
8263 */
Victor Stinner65170952011-11-22 22:16:17 +01008264 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 /* really not much we can do; just leak */
8266 PyErr_Clear();
8267 }
Victor Stinner65170952011-11-22 22:16:17 +01008268 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008269 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008270}
8271#endif /* unsetenv */
8272
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008273PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008274"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008275Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008276
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008278posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008279{
Victor Stinner8c62be82010-05-06 00:08:46 +00008280 int code;
8281 char *message;
8282 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8283 return NULL;
8284 message = strerror(code);
8285 if (message == NULL) {
8286 PyErr_SetString(PyExc_ValueError,
8287 "strerror() argument out of range");
8288 return NULL;
8289 }
Victor Stinner1b579672011-12-17 05:47:23 +01008290 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008291}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008292
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008293
Guido van Rossumc9641791998-08-04 15:26:23 +00008294#ifdef HAVE_SYS_WAIT_H
8295
Fred Drake106c1a02002-04-23 15:58:02 +00008296#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008297PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008298"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008299Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008300
8301static PyObject *
8302posix_WCOREDUMP(PyObject *self, PyObject *args)
8303{
Victor Stinner8c62be82010-05-06 00:08:46 +00008304 WAIT_TYPE status;
8305 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008306
Victor Stinner8c62be82010-05-06 00:08:46 +00008307 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8308 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008309
Victor Stinner8c62be82010-05-06 00:08:46 +00008310 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008311}
8312#endif /* WCOREDUMP */
8313
8314#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008315PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008316"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008317Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008318job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008319
8320static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008321posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008322{
Victor Stinner8c62be82010-05-06 00:08:46 +00008323 WAIT_TYPE status;
8324 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008325
Victor Stinner8c62be82010-05-06 00:08:46 +00008326 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8327 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008328
Victor Stinner8c62be82010-05-06 00:08:46 +00008329 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008330}
8331#endif /* WIFCONTINUED */
8332
Guido van Rossumc9641791998-08-04 15:26:23 +00008333#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008334PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008335"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008336Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008337
8338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008339posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008340{
Victor Stinner8c62be82010-05-06 00:08:46 +00008341 WAIT_TYPE status;
8342 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008343
Victor Stinner8c62be82010-05-06 00:08:46 +00008344 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8345 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008346
Victor Stinner8c62be82010-05-06 00:08:46 +00008347 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008348}
8349#endif /* WIFSTOPPED */
8350
8351#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008352PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008353"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008354Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008355
8356static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008357posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008358{
Victor Stinner8c62be82010-05-06 00:08:46 +00008359 WAIT_TYPE status;
8360 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008361
Victor Stinner8c62be82010-05-06 00:08:46 +00008362 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8363 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008364
Victor Stinner8c62be82010-05-06 00:08:46 +00008365 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008366}
8367#endif /* WIFSIGNALED */
8368
8369#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008370PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008371"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008372Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008373system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008374
8375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008376posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008377{
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 WAIT_TYPE status;
8379 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008380
Victor Stinner8c62be82010-05-06 00:08:46 +00008381 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8382 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008383
Victor Stinner8c62be82010-05-06 00:08:46 +00008384 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008385}
8386#endif /* WIFEXITED */
8387
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008388#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008389PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008390"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008391Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008392
8393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008394posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008395{
Victor Stinner8c62be82010-05-06 00:08:46 +00008396 WAIT_TYPE status;
8397 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008398
Victor Stinner8c62be82010-05-06 00:08:46 +00008399 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8400 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008401
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008403}
8404#endif /* WEXITSTATUS */
8405
8406#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008407PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008408"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008409Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008410value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008411
8412static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008413posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008414{
Victor Stinner8c62be82010-05-06 00:08:46 +00008415 WAIT_TYPE status;
8416 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008417
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8419 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008420
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008422}
8423#endif /* WTERMSIG */
8424
8425#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008426PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008427"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008428Return the signal that stopped the process that provided\n\
8429the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008430
8431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008432posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008433{
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 WAIT_TYPE status;
8435 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008436
Victor Stinner8c62be82010-05-06 00:08:46 +00008437 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8438 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008439
Victor Stinner8c62be82010-05-06 00:08:46 +00008440 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008441}
8442#endif /* WSTOPSIG */
8443
8444#endif /* HAVE_SYS_WAIT_H */
8445
8446
Thomas Wouters477c8d52006-05-27 19:21:47 +00008447#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008448#ifdef _SCO_DS
8449/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8450 needed definitions in sys/statvfs.h */
8451#define _SVID3
8452#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008453#include <sys/statvfs.h>
8454
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008455static PyObject*
8456_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008457 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8458 if (v == NULL)
8459 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008460
8461#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008462 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8463 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8464 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8465 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8466 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8467 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8468 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8469 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8470 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8471 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008472#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008473 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8474 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8475 PyStructSequence_SET_ITEM(v, 2,
8476 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8477 PyStructSequence_SET_ITEM(v, 3,
8478 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8479 PyStructSequence_SET_ITEM(v, 4,
8480 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8481 PyStructSequence_SET_ITEM(v, 5,
8482 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8483 PyStructSequence_SET_ITEM(v, 6,
8484 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8485 PyStructSequence_SET_ITEM(v, 7,
8486 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8487 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8488 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008489#endif
8490
Victor Stinner8c62be82010-05-06 00:08:46 +00008491 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008492}
8493
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008494PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008495"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008496Perform an fstatvfs system call on the given fd.\n\
8497Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008498
8499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008500posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008501{
Victor Stinner8c62be82010-05-06 00:08:46 +00008502 int fd, res;
8503 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008504
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8506 return NULL;
8507 Py_BEGIN_ALLOW_THREADS
8508 res = fstatvfs(fd, &st);
8509 Py_END_ALLOW_THREADS
8510 if (res != 0)
8511 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008512
Victor Stinner8c62be82010-05-06 00:08:46 +00008513 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008514}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008515#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008516
8517
Thomas Wouters477c8d52006-05-27 19:21:47 +00008518#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008519#include <sys/statvfs.h>
8520
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008521PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008522"statvfs(path)\n\n\
8523Perform a statvfs system call on the given path.\n\
8524\n\
8525path may always be specified as a string.\n\
8526On some platforms, path may also be specified as an open file descriptor.\n\
8527 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008528
8529static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008530posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008531{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008532 static char *keywords[] = {"path", NULL};
8533 path_t path;
8534 int result;
8535 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008536 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008537
Larry Hastings9cf065c2012-06-22 16:30:09 -07008538 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008539 path.function_name = "statvfs";
Larry Hastings9cf065c2012-06-22 16:30:09 -07008540#ifdef HAVE_FSTATVFS
8541 path.allow_fd = 1;
8542#endif
8543 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
8544 path_converter, &path
8545 ))
8546 return NULL;
8547
8548 Py_BEGIN_ALLOW_THREADS
8549#ifdef HAVE_FSTATVFS
8550 if (path.fd != -1) {
8551#ifdef __APPLE__
8552 /* handle weak-linking on Mac OS X 10.3 */
8553 if (fstatvfs == NULL) {
8554 fd_specified("statvfs", path.fd);
8555 goto exit;
8556 }
8557#endif
8558 result = fstatvfs(path.fd, &st);
8559 }
8560 else
8561#endif
8562 result = statvfs(path.narrow, &st);
8563 Py_END_ALLOW_THREADS
8564
8565 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01008566 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008567 goto exit;
8568 }
8569
8570 return_value = _pystatvfs_fromstructstatvfs(st);
8571
8572exit:
8573 path_cleanup(&path);
8574 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008575}
8576#endif /* HAVE_STATVFS */
8577
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008578#ifdef MS_WINDOWS
8579PyDoc_STRVAR(win32__getdiskusage__doc__,
8580"_getdiskusage(path) -> (total, free)\n\n\
8581Return disk usage statistics about the given path as (total, free) tuple.");
8582
8583static PyObject *
8584win32__getdiskusage(PyObject *self, PyObject *args)
8585{
8586 BOOL retval;
8587 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008588 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008589
Victor Stinner6139c1b2011-11-09 22:14:14 +01008590 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008591 return NULL;
8592
8593 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008594 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008595 Py_END_ALLOW_THREADS
8596 if (retval == 0)
8597 return PyErr_SetFromWindowsErr(0);
8598
8599 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8600}
8601#endif
8602
8603
Fred Drakec9680921999-12-13 16:37:25 +00008604/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8605 * It maps strings representing configuration variable names to
8606 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008607 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008608 * rarely-used constants. There are three separate tables that use
8609 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008610 *
8611 * This code is always included, even if none of the interfaces that
8612 * need it are included. The #if hackery needed to avoid it would be
8613 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008614 */
8615struct constdef {
8616 char *name;
8617 long value;
8618};
8619
Fred Drake12c6e2d1999-12-14 21:25:03 +00008620static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008621conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008622 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008623{
Christian Heimes217cfd12007-12-02 14:31:20 +00008624 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008625 *valuep = PyLong_AS_LONG(arg);
8626 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008627 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008628 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008629 /* look up the value in the table using a binary search */
8630 size_t lo = 0;
8631 size_t mid;
8632 size_t hi = tablesize;
8633 int cmp;
8634 const char *confname;
8635 if (!PyUnicode_Check(arg)) {
8636 PyErr_SetString(PyExc_TypeError,
8637 "configuration names must be strings or integers");
8638 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008639 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008640 confname = _PyUnicode_AsString(arg);
8641 if (confname == NULL)
8642 return 0;
8643 while (lo < hi) {
8644 mid = (lo + hi) / 2;
8645 cmp = strcmp(confname, table[mid].name);
8646 if (cmp < 0)
8647 hi = mid;
8648 else if (cmp > 0)
8649 lo = mid + 1;
8650 else {
8651 *valuep = table[mid].value;
8652 return 1;
8653 }
8654 }
8655 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8656 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008657 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008658}
8659
8660
8661#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8662static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008663#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008664 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008665#endif
8666#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008667 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008668#endif
Fred Drakec9680921999-12-13 16:37:25 +00008669#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008671#endif
8672#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008673 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008674#endif
8675#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008676 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008677#endif
8678#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008679 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008680#endif
8681#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008683#endif
8684#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008686#endif
8687#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008689#endif
8690#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008691 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008692#endif
8693#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008695#endif
8696#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008697 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008698#endif
8699#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008700 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008701#endif
8702#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008703 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008704#endif
8705#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008707#endif
8708#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008709 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008710#endif
8711#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008713#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008714#ifdef _PC_ACL_ENABLED
8715 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8716#endif
8717#ifdef _PC_MIN_HOLE_SIZE
8718 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8719#endif
8720#ifdef _PC_ALLOC_SIZE_MIN
8721 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8722#endif
8723#ifdef _PC_REC_INCR_XFER_SIZE
8724 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8725#endif
8726#ifdef _PC_REC_MAX_XFER_SIZE
8727 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8728#endif
8729#ifdef _PC_REC_MIN_XFER_SIZE
8730 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8731#endif
8732#ifdef _PC_REC_XFER_ALIGN
8733 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8734#endif
8735#ifdef _PC_SYMLINK_MAX
8736 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8737#endif
8738#ifdef _PC_XATTR_ENABLED
8739 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8740#endif
8741#ifdef _PC_XATTR_EXISTS
8742 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8743#endif
8744#ifdef _PC_TIMESTAMP_RESOLUTION
8745 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8746#endif
Fred Drakec9680921999-12-13 16:37:25 +00008747};
8748
Fred Drakec9680921999-12-13 16:37:25 +00008749static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008750conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008751{
8752 return conv_confname(arg, valuep, posix_constants_pathconf,
8753 sizeof(posix_constants_pathconf)
8754 / sizeof(struct constdef));
8755}
8756#endif
8757
8758#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008759PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008760"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008761Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008762If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008763
8764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008765posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008766{
8767 PyObject *result = NULL;
8768 int name, fd;
8769
Fred Drake12c6e2d1999-12-14 21:25:03 +00008770 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8771 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008772 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008773
Stefan Krah0e803b32010-11-26 16:16:47 +00008774 errno = 0;
8775 limit = fpathconf(fd, name);
8776 if (limit == -1 && errno != 0)
8777 posix_error();
8778 else
8779 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008780 }
8781 return result;
8782}
8783#endif
8784
8785
8786#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008787PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008788"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008789Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008790If there is no limit, return -1.\n\
8791On some platforms, path may also be specified as an open file descriptor.\n\
8792 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00008793
8794static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008795posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00008796{
Georg Brandl306336b2012-06-24 12:55:33 +02008797 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00008798 PyObject *result = NULL;
8799 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02008800 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00008801
Georg Brandl306336b2012-06-24 12:55:33 +02008802 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01008803 path.function_name = "pathconf";
Georg Brandl306336b2012-06-24 12:55:33 +02008804#ifdef HAVE_FPATHCONF
8805 path.allow_fd = 1;
8806#endif
8807 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
8808 path_converter, &path,
8809 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008810 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008811
Victor Stinner8c62be82010-05-06 00:08:46 +00008812 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02008813#ifdef HAVE_FPATHCONF
8814 if (path.fd != -1)
8815 limit = fpathconf(path.fd, name);
8816 else
8817#endif
8818 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00008819 if (limit == -1 && errno != 0) {
8820 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008821 /* could be a path or name problem */
8822 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008823 else
Victor Stinner292c8352012-10-30 02:17:38 +01008824 result = path_error(&path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008825 }
8826 else
8827 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008828 }
Georg Brandl306336b2012-06-24 12:55:33 +02008829 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00008830 return result;
8831}
8832#endif
8833
8834#ifdef HAVE_CONFSTR
8835static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008836#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008838#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008839#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008841#endif
8842#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008844#endif
Fred Draked86ed291999-12-15 15:34:33 +00008845#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008846 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008847#endif
8848#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008849 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008850#endif
8851#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008853#endif
8854#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008856#endif
Fred Drakec9680921999-12-13 16:37:25 +00008857#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008859#endif
8860#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008862#endif
8863#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008864 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008865#endif
8866#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008867 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008868#endif
8869#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008870 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008871#endif
8872#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008874#endif
8875#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008876 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008877#endif
8878#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008879 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008880#endif
Fred Draked86ed291999-12-15 15:34:33 +00008881#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008882 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008883#endif
Fred Drakec9680921999-12-13 16:37:25 +00008884#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008885 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008886#endif
Fred Draked86ed291999-12-15 15:34:33 +00008887#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008888 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008889#endif
8890#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008891 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008892#endif
8893#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008894 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008895#endif
8896#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008897 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008898#endif
Fred Drakec9680921999-12-13 16:37:25 +00008899#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008900 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008901#endif
8902#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008903 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008904#endif
8905#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008906 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008907#endif
8908#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008909 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008910#endif
8911#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008912 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008913#endif
8914#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008915 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008916#endif
8917#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008918 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008919#endif
8920#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008921 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008922#endif
8923#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008924 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008925#endif
8926#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008927 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008928#endif
8929#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008930 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008931#endif
8932#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008933 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008934#endif
8935#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008937#endif
8938#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008940#endif
8941#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008943#endif
8944#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008946#endif
Fred Draked86ed291999-12-15 15:34:33 +00008947#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008949#endif
8950#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008952#endif
8953#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008954 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008955#endif
8956#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008957 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008958#endif
8959#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008960 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008961#endif
8962#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008963 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008964#endif
8965#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008966 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008967#endif
8968#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008969 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008970#endif
8971#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008972 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008973#endif
8974#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008975 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008976#endif
8977#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008978 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008979#endif
8980#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008981 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008982#endif
8983#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008984 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008985#endif
Fred Drakec9680921999-12-13 16:37:25 +00008986};
8987
8988static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008989conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008990{
8991 return conv_confname(arg, valuep, posix_constants_confstr,
8992 sizeof(posix_constants_confstr)
8993 / sizeof(struct constdef));
8994}
8995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008996PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008997"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008998Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008999
9000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009001posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009002{
9003 PyObject *result = NULL;
9004 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009005 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009006 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009007
Victor Stinnercb043522010-09-10 23:49:04 +00009008 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9009 return NULL;
9010
9011 errno = 0;
9012 len = confstr(name, buffer, sizeof(buffer));
9013 if (len == 0) {
9014 if (errno) {
9015 posix_error();
9016 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009017 }
9018 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009019 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009020 }
9021 }
Victor Stinnercb043522010-09-10 23:49:04 +00009022
9023 if ((unsigned int)len >= sizeof(buffer)) {
9024 char *buf = PyMem_Malloc(len);
9025 if (buf == NULL)
9026 return PyErr_NoMemory();
9027 confstr(name, buf, len);
9028 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9029 PyMem_Free(buf);
9030 }
9031 else
9032 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009033 return result;
9034}
9035#endif
9036
9037
9038#ifdef HAVE_SYSCONF
9039static struct constdef posix_constants_sysconf[] = {
9040#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009041 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009042#endif
9043#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009044 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009045#endif
9046#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009047 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009048#endif
9049#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009050 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009051#endif
9052#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009054#endif
9055#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009056 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009057#endif
9058#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009059 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009060#endif
9061#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009063#endif
9064#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009065 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009066#endif
9067#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009069#endif
Fred Draked86ed291999-12-15 15:34:33 +00009070#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009072#endif
9073#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009074 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009075#endif
Fred Drakec9680921999-12-13 16:37:25 +00009076#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009078#endif
Fred Drakec9680921999-12-13 16:37:25 +00009079#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009081#endif
9082#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009084#endif
9085#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009087#endif
9088#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009090#endif
9091#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009092 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009093#endif
Fred Draked86ed291999-12-15 15:34:33 +00009094#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009096#endif
Fred Drakec9680921999-12-13 16:37:25 +00009097#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009098 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009099#endif
9100#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009102#endif
9103#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009104 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009105#endif
9106#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009107 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009108#endif
9109#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009110 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009111#endif
Fred Draked86ed291999-12-15 15:34:33 +00009112#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009114#endif
Fred Drakec9680921999-12-13 16:37:25 +00009115#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009117#endif
9118#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009119 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009120#endif
9121#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009123#endif
9124#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009125 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009126#endif
9127#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009128 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009129#endif
9130#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009131 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009132#endif
9133#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009134 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009135#endif
9136#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009137 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009138#endif
9139#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009140 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009141#endif
9142#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009144#endif
9145#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009147#endif
9148#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009149 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009150#endif
9151#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009152 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009153#endif
9154#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009155 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009156#endif
9157#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009159#endif
9160#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009162#endif
9163#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009165#endif
9166#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009168#endif
9169#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009170 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009171#endif
9172#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009173 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009174#endif
9175#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009176 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009177#endif
9178#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009179 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009180#endif
9181#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009182 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009183#endif
Fred Draked86ed291999-12-15 15:34:33 +00009184#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009185 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009186#endif
Fred Drakec9680921999-12-13 16:37:25 +00009187#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009188 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009189#endif
9190#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009191 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009192#endif
9193#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009195#endif
Fred Draked86ed291999-12-15 15:34:33 +00009196#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009197 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009198#endif
Fred Drakec9680921999-12-13 16:37:25 +00009199#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009200 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009201#endif
Fred Draked86ed291999-12-15 15:34:33 +00009202#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009203 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009204#endif
9205#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009206 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009207#endif
Fred Drakec9680921999-12-13 16:37:25 +00009208#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009209 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009210#endif
9211#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009212 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009213#endif
9214#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009215 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009216#endif
9217#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009218 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009219#endif
Fred Draked86ed291999-12-15 15:34:33 +00009220#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009221 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009222#endif
Fred Drakec9680921999-12-13 16:37:25 +00009223#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009224 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009225#endif
9226#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009227 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009228#endif
9229#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009230 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009231#endif
9232#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009233 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009234#endif
9235#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009236 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009237#endif
9238#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009239 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009240#endif
9241#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009242 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009243#endif
Fred Draked86ed291999-12-15 15:34:33 +00009244#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009245 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009246#endif
Fred Drakec9680921999-12-13 16:37:25 +00009247#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009248 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009249#endif
9250#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009251 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009252#endif
Fred Draked86ed291999-12-15 15:34:33 +00009253#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009254 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009255#endif
Fred Drakec9680921999-12-13 16:37:25 +00009256#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009258#endif
9259#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009260 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009261#endif
9262#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009263 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009264#endif
9265#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009266 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009267#endif
9268#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009269 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009270#endif
9271#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009272 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009273#endif
9274#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009275 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009276#endif
9277#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009279#endif
9280#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009281 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009282#endif
Fred Draked86ed291999-12-15 15:34:33 +00009283#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009284 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009285#endif
9286#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009287 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009288#endif
Fred Drakec9680921999-12-13 16:37:25 +00009289#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009290 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009291#endif
9292#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009293 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009294#endif
9295#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009296 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009297#endif
9298#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009299 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009300#endif
9301#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009302 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009303#endif
9304#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009306#endif
9307#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009309#endif
9310#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009312#endif
9313#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009315#endif
9316#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009318#endif
9319#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009321#endif
9322#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009324#endif
9325#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009327#endif
9328#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009330#endif
9331#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009333#endif
9334#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009336#endif
9337#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009339#endif
9340#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009342#endif
9343#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009345#endif
9346#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009348#endif
9349#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009351#endif
9352#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009354#endif
9355#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009357#endif
9358#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009360#endif
9361#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
9370#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009372#endif
9373#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009375#endif
9376#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009378#endif
9379#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009381#endif
9382#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009384#endif
9385#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009387#endif
9388#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009390#endif
9391#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009393#endif
Fred Draked86ed291999-12-15 15:34:33 +00009394#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009396#endif
Fred Drakec9680921999-12-13 16:37:25 +00009397#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009399#endif
9400#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009402#endif
9403#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009404 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009405#endif
9406#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009407 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009408#endif
9409#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009410 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009411#endif
9412#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009413 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009414#endif
9415#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009416 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009417#endif
9418#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009419 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009420#endif
9421#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009422 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009423#endif
9424#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009425 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009426#endif
9427#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009428 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009429#endif
9430#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009431 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009432#endif
9433#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009434 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009435#endif
9436#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009437 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009438#endif
9439#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009440 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009441#endif
9442#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009443 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009444#endif
9445#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009446 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009447#endif
9448#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009449 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009450#endif
9451#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009452 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009453#endif
9454#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009455 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009456#endif
9457#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009458 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009459#endif
9460#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009461 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009462#endif
9463#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009464 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009465#endif
9466#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009467 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009468#endif
9469#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009470 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009471#endif
9472#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009473 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009474#endif
9475#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009476 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009477#endif
9478#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009479 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009480#endif
9481#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009482 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009483#endif
9484#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009485 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009486#endif
9487#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009489#endif
9490#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009491 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009492#endif
9493#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009494 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009495#endif
9496#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009498#endif
9499#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009500 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009501#endif
9502#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009503 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009504#endif
9505#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009506 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009507#endif
9508#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009510#endif
9511#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009513#endif
9514#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009516#endif
9517#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009519#endif
9520#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009522#endif
9523#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009525#endif
9526#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009528#endif
9529#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009531#endif
9532};
9533
9534static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009535conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009536{
9537 return conv_confname(arg, valuep, posix_constants_sysconf,
9538 sizeof(posix_constants_sysconf)
9539 / sizeof(struct constdef));
9540}
9541
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009542PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009543"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009544Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009545
9546static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009547posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009548{
9549 PyObject *result = NULL;
9550 int name;
9551
9552 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9553 int value;
9554
9555 errno = 0;
9556 value = sysconf(name);
9557 if (value == -1 && errno != 0)
9558 posix_error();
9559 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009560 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009561 }
9562 return result;
9563}
9564#endif
9565
9566
Fred Drakebec628d1999-12-15 18:31:10 +00009567/* This code is used to ensure that the tables of configuration value names
9568 * are in sorted order as required by conv_confname(), and also to build the
9569 * the exported dictionaries that are used to publish information about the
9570 * names available on the host platform.
9571 *
9572 * Sorting the table at runtime ensures that the table is properly ordered
9573 * when used, even for platforms we're not able to test on. It also makes
9574 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009575 */
Fred Drakebec628d1999-12-15 18:31:10 +00009576
9577static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009578cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009579{
9580 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009582 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009584
9585 return strcmp(c1->name, c2->name);
9586}
9587
9588static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009589setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009591{
Fred Drakebec628d1999-12-15 18:31:10 +00009592 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009593 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009594
9595 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9596 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009597 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009599
Barry Warsaw3155db32000-04-13 15:20:40 +00009600 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 PyObject *o = PyLong_FromLong(table[i].value);
9602 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9603 Py_XDECREF(o);
9604 Py_DECREF(d);
9605 return -1;
9606 }
9607 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009608 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009609 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009610}
9611
Fred Drakebec628d1999-12-15 18:31:10 +00009612/* Return -1 on failure, 0 on success. */
9613static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009614setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009615{
9616#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009617 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009618 sizeof(posix_constants_pathconf)
9619 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009620 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009621 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009622#endif
9623#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009624 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009625 sizeof(posix_constants_confstr)
9626 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009627 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009628 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009629#endif
9630#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009631 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009632 sizeof(posix_constants_sysconf)
9633 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009634 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009635 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009636#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009637 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009638}
Fred Draked86ed291999-12-15 15:34:33 +00009639
9640
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009641PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009642"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009643Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009644in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009645
9646static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009647posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009648{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009649 abort();
9650 /*NOTREACHED*/
9651 Py_FatalError("abort() called from Python code didn't abort!");
9652 return NULL;
9653}
Fred Drakebec628d1999-12-15 18:31:10 +00009654
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009655#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009656PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009657"startfile(filepath [, operation]) - Start a file with its associated\n\
9658application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009659\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009660When \"operation\" is not specified or \"open\", this acts like\n\
9661double-clicking the file in Explorer, or giving the file name as an\n\
9662argument to the DOS \"start\" command: the file is opened with whatever\n\
9663application (if any) its extension is associated.\n\
9664When another \"operation\" is given, it specifies what should be done with\n\
9665the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009666\n\
9667startfile returns as soon as the associated application is launched.\n\
9668There is no option to wait for the application to close, and no way\n\
9669to retrieve the application's exit status.\n\
9670\n\
9671The filepath is relative to the current directory. If you want to use\n\
9672an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009673the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009674
9675static PyObject *
9676win32_startfile(PyObject *self, PyObject *args)
9677{
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 PyObject *ofilepath;
9679 char *filepath;
9680 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009681 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009683
Victor Stinnereb5657a2011-09-30 01:44:27 +02009684 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 if (!PyArg_ParseTuple(args, "U|s:startfile",
9686 &unipath, &operation)) {
9687 PyErr_Clear();
9688 goto normal;
9689 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009690
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009692 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009694 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 PyErr_Clear();
9696 operation = NULL;
9697 goto normal;
9698 }
9699 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009700
Victor Stinnereb5657a2011-09-30 01:44:27 +02009701 wpath = PyUnicode_AsUnicode(unipath);
9702 if (wpath == NULL)
9703 goto normal;
9704 if (uoperation) {
9705 woperation = PyUnicode_AsUnicode(uoperation);
9706 if (woperation == NULL)
9707 goto normal;
9708 }
9709 else
9710 woperation = NULL;
9711
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009713 rc = ShellExecuteW((HWND)0, woperation, wpath,
9714 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 Py_END_ALLOW_THREADS
9716
Victor Stinnereb5657a2011-09-30 01:44:27 +02009717 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009719 win32_error_object("startfile", unipath);
9720 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 }
9722 Py_INCREF(Py_None);
9723 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009724
9725normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9727 PyUnicode_FSConverter, &ofilepath,
9728 &operation))
9729 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009730 if (win32_warn_bytes_api()) {
9731 Py_DECREF(ofilepath);
9732 return NULL;
9733 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 filepath = PyBytes_AsString(ofilepath);
9735 Py_BEGIN_ALLOW_THREADS
9736 rc = ShellExecute((HWND)0, operation, filepath,
9737 NULL, NULL, SW_SHOWNORMAL);
9738 Py_END_ALLOW_THREADS
9739 if (rc <= (HINSTANCE)32) {
9740 PyObject *errval = win32_error("startfile", filepath);
9741 Py_DECREF(ofilepath);
9742 return errval;
9743 }
9744 Py_DECREF(ofilepath);
9745 Py_INCREF(Py_None);
9746 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009747}
9748#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009749
Martin v. Löwis438b5342002-12-27 10:16:42 +00009750#ifdef HAVE_GETLOADAVG
9751PyDoc_STRVAR(posix_getloadavg__doc__,
9752"getloadavg() -> (float, float, float)\n\n\
9753Return the number of processes in the system run queue averaged over\n\
9754the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9755was unobtainable");
9756
9757static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009758posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009759{
9760 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009761 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009762 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9763 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009764 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009765 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009766}
9767#endif
9768
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009769PyDoc_STRVAR(device_encoding__doc__,
9770"device_encoding(fd) -> str\n\n\
9771Return a string describing the encoding of the device\n\
9772if the output is a terminal; else return None.");
9773
9774static PyObject *
9775device_encoding(PyObject *self, PyObject *args)
9776{
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -05009778
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9780 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -05009781
9782 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009783}
9784
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009785#ifdef HAVE_SETRESUID
9786PyDoc_STRVAR(posix_setresuid__doc__,
9787"setresuid(ruid, euid, suid)\n\n\
9788Set the current process's real, effective, and saved user ids.");
9789
9790static PyObject*
9791posix_setresuid (PyObject *self, PyObject *args)
9792{
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009794 uid_t ruid, euid, suid;
9795 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
9796 _Py_Uid_Converter, &ruid,
9797 _Py_Uid_Converter, &euid,
9798 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 return NULL;
9800 if (setresuid(ruid, euid, suid) < 0)
9801 return posix_error();
9802 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009803}
9804#endif
9805
9806#ifdef HAVE_SETRESGID
9807PyDoc_STRVAR(posix_setresgid__doc__,
9808"setresgid(rgid, egid, sgid)\n\n\
9809Set the current process's real, effective, and saved group ids.");
9810
9811static PyObject*
9812posix_setresgid (PyObject *self, PyObject *args)
9813{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009814 gid_t rgid, egid, sgid;
9815 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
9816 _Py_Gid_Converter, &rgid,
9817 _Py_Gid_Converter, &egid,
9818 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 return NULL;
9820 if (setresgid(rgid, egid, sgid) < 0)
9821 return posix_error();
9822 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009823}
9824#endif
9825
9826#ifdef HAVE_GETRESUID
9827PyDoc_STRVAR(posix_getresuid__doc__,
9828"getresuid() -> (ruid, euid, suid)\n\n\
9829Get tuple of the current process's real, effective, and saved user ids.");
9830
9831static PyObject*
9832posix_getresuid (PyObject *self, PyObject *noargs)
9833{
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 if (getresuid(&ruid, &euid, &suid) < 0)
9836 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009837 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
9838 _PyLong_FromUid(euid),
9839 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009840}
9841#endif
9842
9843#ifdef HAVE_GETRESGID
9844PyDoc_STRVAR(posix_getresgid__doc__,
9845"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009846Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009847
9848static PyObject*
9849posix_getresgid (PyObject *self, PyObject *noargs)
9850{
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 if (getresgid(&rgid, &egid, &sgid) < 0)
9853 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02009854 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
9855 _PyLong_FromGid(egid),
9856 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009857}
9858#endif
9859
Benjamin Peterson9428d532011-09-14 11:45:52 -04009860#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -04009861
Benjamin Peterson799bd802011-08-31 22:15:17 -04009862PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009863"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
9864Return the value of extended attribute attribute on path.\n\
9865\n\
9866path may be either a string or an open file descriptor.\n\
9867If follow_symlinks is False, and the last element of the path is a symbolic\n\
9868 link, getxattr will examine the symbolic link itself instead of the file\n\
9869 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009870
9871static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009872posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009873{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009874 path_t path;
9875 path_t attribute;
9876 int follow_symlinks = 1;
9877 PyObject *buffer = NULL;
9878 int i;
9879 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009880
Larry Hastings9cf065c2012-06-22 16:30:09 -07009881 memset(&path, 0, sizeof(path));
9882 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +01009883 path.function_name = "getxattr";
9884 attribute.function_name = "getxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009885 path.allow_fd = 1;
9886 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
9887 path_converter, &path,
9888 path_converter, &attribute,
9889 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009890 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009891
Larry Hastings9cf065c2012-06-22 16:30:09 -07009892 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
9893 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009894
Larry Hastings9cf065c2012-06-22 16:30:09 -07009895 for (i = 0; ; i++) {
9896 void *ptr;
9897 ssize_t result;
9898 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
9899 Py_ssize_t buffer_size = buffer_sizes[i];
9900 if (!buffer_size) {
Victor Stinner292c8352012-10-30 02:17:38 +01009901 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009902 goto exit;
9903 }
9904 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
9905 if (!buffer)
9906 goto exit;
9907 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009908
Larry Hastings9cf065c2012-06-22 16:30:09 -07009909 Py_BEGIN_ALLOW_THREADS;
9910 if (path.fd >= 0)
9911 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
9912 else if (follow_symlinks)
9913 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9914 else
9915 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
9916 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009917
Larry Hastings9cf065c2012-06-22 16:30:09 -07009918 if (result < 0) {
9919 Py_DECREF(buffer);
9920 buffer = NULL;
9921 if (errno == ERANGE)
9922 continue;
Victor Stinner292c8352012-10-30 02:17:38 +01009923 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009924 goto exit;
9925 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009926
Larry Hastings9cf065c2012-06-22 16:30:09 -07009927 if (result != buffer_size) {
9928 /* Can only shrink. */
9929 _PyBytes_Resize(&buffer, result);
9930 }
9931 break;
9932 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009933
Larry Hastings9cf065c2012-06-22 16:30:09 -07009934exit:
9935 path_cleanup(&path);
9936 path_cleanup(&attribute);
9937 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009938}
9939
9940PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009941"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
9942Set extended attribute attribute on path to value.\n\
9943path may be either a string or an open file descriptor.\n\
9944If follow_symlinks is False, and the last element of the path is a symbolic\n\
9945 link, setxattr will modify the symbolic link itself instead of the file\n\
9946 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -04009947
9948static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009949posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -04009950{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009951 path_t path;
9952 path_t attribute;
9953 Py_buffer value;
9954 int flags = 0;
9955 int follow_symlinks = 1;
9956 int result;
9957 PyObject *return_value = NULL;
9958 static char *keywords[] = {"path", "attribute", "value",
9959 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -04009960
Larry Hastings9cf065c2012-06-22 16:30:09 -07009961 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01009962 path.function_name = "setxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -07009963 path.allow_fd = 1;
9964 memset(&attribute, 0, sizeof(attribute));
9965 memset(&value, 0, sizeof(value));
9966 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
9967 keywords,
9968 path_converter, &path,
9969 path_converter, &attribute,
9970 &value, &flags,
9971 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -04009972 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009973
9974 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
9975 goto exit;
9976
Benjamin Peterson799bd802011-08-31 22:15:17 -04009977 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009978 if (path.fd > -1)
9979 result = fsetxattr(path.fd, attribute.narrow,
9980 value.buf, value.len, flags);
9981 else if (follow_symlinks)
9982 result = setxattr(path.narrow, attribute.narrow,
9983 value.buf, value.len, flags);
9984 else
9985 result = lsetxattr(path.narrow, attribute.narrow,
9986 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009987 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -04009988
Larry Hastings9cf065c2012-06-22 16:30:09 -07009989 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +01009990 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009991 goto exit;
9992 }
Benjamin Peterson799bd802011-08-31 22:15:17 -04009993
Larry Hastings9cf065c2012-06-22 16:30:09 -07009994 return_value = Py_None;
9995 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -04009996
Larry Hastings9cf065c2012-06-22 16:30:09 -07009997exit:
9998 path_cleanup(&path);
9999 path_cleanup(&attribute);
10000 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010001
Larry Hastings9cf065c2012-06-22 16:30:09 -070010002 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010003}
10004
10005PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010006"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10007Remove extended attribute attribute on path.\n\
10008path may be either a string or an open file descriptor.\n\
10009If follow_symlinks is False, and the last element of the path is a symbolic\n\
10010 link, removexattr will modify the symbolic link itself instead of the file\n\
10011 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010012
10013static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010014posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010015{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010016 path_t path;
10017 path_t attribute;
10018 int follow_symlinks = 1;
10019 int result;
10020 PyObject *return_value = NULL;
10021 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010022
Larry Hastings9cf065c2012-06-22 16:30:09 -070010023 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010024 path.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010025 memset(&attribute, 0, sizeof(attribute));
Victor Stinner292c8352012-10-30 02:17:38 +010010026 attribute.function_name = "removexattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010027 path.allow_fd = 1;
10028 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10029 keywords,
10030 path_converter, &path,
10031 path_converter, &attribute,
10032 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010033 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010034
10035 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10036 goto exit;
10037
Benjamin Peterson799bd802011-08-31 22:15:17 -040010038 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010039 if (path.fd > -1)
10040 result = fremovexattr(path.fd, attribute.narrow);
10041 else if (follow_symlinks)
10042 result = removexattr(path.narrow, attribute.narrow);
10043 else
10044 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010045 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010046
Larry Hastings9cf065c2012-06-22 16:30:09 -070010047 if (result) {
Victor Stinner292c8352012-10-30 02:17:38 +010010048 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010049 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010050 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010051
Larry Hastings9cf065c2012-06-22 16:30:09 -070010052 return_value = Py_None;
10053 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010054
Larry Hastings9cf065c2012-06-22 16:30:09 -070010055exit:
10056 path_cleanup(&path);
10057 path_cleanup(&attribute);
10058
10059 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010060}
10061
10062PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010063"listxattr(path='.', *, follow_symlinks=True)\n\n\
10064Return a list of extended attributes on path.\n\
10065\n\
10066path may be either None, a string, or an open file descriptor.\n\
10067if path is None, listxattr will examine the current directory.\n\
10068If follow_symlinks is False, and the last element of the path is a symbolic\n\
10069 link, listxattr will examine the symbolic link itself instead of the file\n\
10070 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010071
10072static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010073posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010074{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010075 path_t path;
10076 int follow_symlinks = 1;
10077 Py_ssize_t i;
10078 PyObject *result = NULL;
10079 char *buffer = NULL;
10080 char *name;
10081 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010082
Larry Hastings9cf065c2012-06-22 16:30:09 -070010083 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +010010084 path.function_name = "listxattr";
Larry Hastings9cf065c2012-06-22 16:30:09 -070010085 path.allow_fd = 1;
10086 path.fd = -1;
10087 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10088 path_converter, &path,
10089 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010090 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010091
Larry Hastings9cf065c2012-06-22 16:30:09 -070010092 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10093 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010094
Larry Hastings9cf065c2012-06-22 16:30:09 -070010095 name = path.narrow ? path.narrow : ".";
10096 for (i = 0; ; i++) {
10097 char *start, *trace, *end;
10098 ssize_t length;
10099 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10100 Py_ssize_t buffer_size = buffer_sizes[i];
10101 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010102 /* ERANGE */
Victor Stinner292c8352012-10-30 02:17:38 +010010103 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010104 break;
10105 }
10106 buffer = PyMem_MALLOC(buffer_size);
10107 if (!buffer) {
10108 PyErr_NoMemory();
10109 break;
10110 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010111
Larry Hastings9cf065c2012-06-22 16:30:09 -070010112 Py_BEGIN_ALLOW_THREADS;
10113 if (path.fd > -1)
10114 length = flistxattr(path.fd, buffer, buffer_size);
10115 else if (follow_symlinks)
10116 length = listxattr(name, buffer, buffer_size);
10117 else
10118 length = llistxattr(name, buffer, buffer_size);
10119 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010120
Larry Hastings9cf065c2012-06-22 16:30:09 -070010121 if (length < 0) {
10122 if (errno == ERANGE)
10123 continue;
Victor Stinner292c8352012-10-30 02:17:38 +010010124 path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010125 break;
10126 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010127
Larry Hastings9cf065c2012-06-22 16:30:09 -070010128 result = PyList_New(0);
10129 if (!result) {
10130 goto exit;
10131 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010132
Larry Hastings9cf065c2012-06-22 16:30:09 -070010133 end = buffer + length;
10134 for (trace = start = buffer; trace != end; trace++) {
10135 if (!*trace) {
10136 int error;
10137 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10138 trace - start);
10139 if (!attribute) {
10140 Py_DECREF(result);
10141 result = NULL;
10142 goto exit;
10143 }
10144 error = PyList_Append(result, attribute);
10145 Py_DECREF(attribute);
10146 if (error) {
10147 Py_DECREF(result);
10148 result = NULL;
10149 goto exit;
10150 }
10151 start = trace + 1;
10152 }
10153 }
10154 break;
10155 }
10156exit:
10157 path_cleanup(&path);
10158 if (buffer)
10159 PyMem_FREE(buffer);
10160 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010161}
10162
Benjamin Peterson9428d532011-09-14 11:45:52 -040010163#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010164
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010165
Georg Brandl2fb477c2012-02-21 00:33:36 +010010166PyDoc_STRVAR(posix_urandom__doc__,
10167"urandom(n) -> str\n\n\
10168Return n random bytes suitable for cryptographic use.");
10169
10170static PyObject *
10171posix_urandom(PyObject *self, PyObject *args)
10172{
10173 Py_ssize_t size;
10174 PyObject *result;
10175 int ret;
10176
10177 /* Read arguments */
10178 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10179 return NULL;
10180 if (size < 0)
10181 return PyErr_Format(PyExc_ValueError,
10182 "negative argument not allowed");
10183 result = PyBytes_FromStringAndSize(NULL, size);
10184 if (result == NULL)
10185 return NULL;
10186
10187 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10188 PyBytes_GET_SIZE(result));
10189 if (ret == -1) {
10190 Py_DECREF(result);
10191 return NULL;
10192 }
10193 return result;
10194}
10195
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010196/* Terminal size querying */
10197
10198static PyTypeObject TerminalSizeType;
10199
10200PyDoc_STRVAR(TerminalSize_docstring,
10201 "A tuple of (columns, lines) for holding terminal window size");
10202
10203static PyStructSequence_Field TerminalSize_fields[] = {
10204 {"columns", "width of the terminal window in characters"},
10205 {"lines", "height of the terminal window in characters"},
10206 {NULL, NULL}
10207};
10208
10209static PyStructSequence_Desc TerminalSize_desc = {
10210 "os.terminal_size",
10211 TerminalSize_docstring,
10212 TerminalSize_fields,
10213 2,
10214};
10215
10216#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10217PyDoc_STRVAR(termsize__doc__,
10218 "Return the size of the terminal window as (columns, lines).\n" \
10219 "\n" \
10220 "The optional argument fd (default standard output) specifies\n" \
10221 "which file descriptor should be queried.\n" \
10222 "\n" \
10223 "If the file descriptor is not connected to a terminal, an OSError\n" \
10224 "is thrown.\n" \
10225 "\n" \
10226 "This function will only be defined if an implementation is\n" \
10227 "available for this system.\n" \
10228 "\n" \
10229 "shutil.get_terminal_size is the high-level function which should \n" \
10230 "normally be used, os.get_terminal_size is the low-level implementation.");
10231
10232static PyObject*
10233get_terminal_size(PyObject *self, PyObject *args)
10234{
10235 int columns, lines;
10236 PyObject *termsize;
10237
10238 int fd = fileno(stdout);
10239 /* Under some conditions stdout may not be connected and
10240 * fileno(stdout) may point to an invalid file descriptor. For example
10241 * GUI apps don't have valid standard streams by default.
10242 *
10243 * If this happens, and the optional fd argument is not present,
10244 * the ioctl below will fail returning EBADF. This is what we want.
10245 */
10246
10247 if (!PyArg_ParseTuple(args, "|i", &fd))
10248 return NULL;
10249
10250#ifdef TERMSIZE_USE_IOCTL
10251 {
10252 struct winsize w;
10253 if (ioctl(fd, TIOCGWINSZ, &w))
10254 return PyErr_SetFromErrno(PyExc_OSError);
10255 columns = w.ws_col;
10256 lines = w.ws_row;
10257 }
10258#endif /* TERMSIZE_USE_IOCTL */
10259
10260#ifdef TERMSIZE_USE_CONIO
10261 {
10262 DWORD nhandle;
10263 HANDLE handle;
10264 CONSOLE_SCREEN_BUFFER_INFO csbi;
10265 switch (fd) {
10266 case 0: nhandle = STD_INPUT_HANDLE;
10267 break;
10268 case 1: nhandle = STD_OUTPUT_HANDLE;
10269 break;
10270 case 2: nhandle = STD_ERROR_HANDLE;
10271 break;
10272 default:
10273 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10274 }
10275 handle = GetStdHandle(nhandle);
10276 if (handle == NULL)
10277 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10278 if (handle == INVALID_HANDLE_VALUE)
10279 return PyErr_SetFromWindowsErr(0);
10280
10281 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10282 return PyErr_SetFromWindowsErr(0);
10283
10284 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10285 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10286 }
10287#endif /* TERMSIZE_USE_CONIO */
10288
10289 termsize = PyStructSequence_New(&TerminalSizeType);
10290 if (termsize == NULL)
10291 return NULL;
10292 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10293 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10294 if (PyErr_Occurred()) {
10295 Py_DECREF(termsize);
10296 return NULL;
10297 }
10298 return termsize;
10299}
10300#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10301
10302
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010303static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010304 {"access", (PyCFunction)posix_access,
10305 METH_VARARGS | METH_KEYWORDS,
10306 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010307#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010309#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010310 {"chdir", (PyCFunction)posix_chdir,
10311 METH_VARARGS | METH_KEYWORDS,
10312 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010313#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010314 {"chflags", (PyCFunction)posix_chflags,
10315 METH_VARARGS | METH_KEYWORDS,
10316 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010317#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010318 {"chmod", (PyCFunction)posix_chmod,
10319 METH_VARARGS | METH_KEYWORDS,
10320 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010321#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010323#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010324#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010325 {"chown", (PyCFunction)posix_chown,
10326 METH_VARARGS | METH_KEYWORDS,
10327 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010328#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010329#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010331#endif /* HAVE_LCHMOD */
10332#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010334#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010335#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010337#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010338#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010340#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010341#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010343#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010344#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010346#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010347#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10349 METH_NOARGS, posix_getcwd__doc__},
10350 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10351 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010352#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010353#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10354 {"link", (PyCFunction)posix_link,
10355 METH_VARARGS | METH_KEYWORDS,
10356 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010357#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010358 {"listdir", (PyCFunction)posix_listdir,
10359 METH_VARARGS | METH_KEYWORDS,
10360 posix_listdir__doc__},
10361 {"lstat", (PyCFunction)posix_lstat,
10362 METH_VARARGS | METH_KEYWORDS,
10363 posix_lstat__doc__},
10364 {"mkdir", (PyCFunction)posix_mkdir,
10365 METH_VARARGS | METH_KEYWORDS,
10366 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010367#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010369#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010370#ifdef HAVE_GETPRIORITY
10371 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10372#endif /* HAVE_GETPRIORITY */
10373#ifdef HAVE_SETPRIORITY
10374 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10375#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010376#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010377 {"readlink", (PyCFunction)posix_readlink,
10378 METH_VARARGS | METH_KEYWORDS,
10379 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010380#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010381#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010382 {"readlink", (PyCFunction)win_readlink,
10383 METH_VARARGS | METH_KEYWORDS,
10384 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010385#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010386 {"rename", (PyCFunction)posix_rename,
10387 METH_VARARGS | METH_KEYWORDS,
10388 posix_rename__doc__},
10389 {"replace", (PyCFunction)posix_replace,
10390 METH_VARARGS | METH_KEYWORDS,
10391 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010392 {"rmdir", (PyCFunction)posix_rmdir,
10393 METH_VARARGS | METH_KEYWORDS,
10394 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010395 {"stat", (PyCFunction)posix_stat,
10396 METH_VARARGS | METH_KEYWORDS,
10397 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010399#if defined(HAVE_SYMLINK)
10400 {"symlink", (PyCFunction)posix_symlink,
10401 METH_VARARGS | METH_KEYWORDS,
10402 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010403#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010404#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010406#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010408#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010410#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010411 {"unlink", (PyCFunction)posix_unlink,
10412 METH_VARARGS | METH_KEYWORDS,
10413 posix_unlink__doc__},
10414 {"remove", (PyCFunction)posix_unlink,
10415 METH_VARARGS | METH_KEYWORDS,
10416 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010417 {"utime", (PyCFunction)posix_utime,
10418 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010419#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010421#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010423#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010425 {"execve", (PyCFunction)posix_execve,
10426 METH_VARARGS | METH_KEYWORDS,
10427 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010428#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010429#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10431 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +000010432#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010433#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010434 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010435#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010436#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010437 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010438#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010439#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010440#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010441 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10442 {"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 +020010443#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010444#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010445 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010446#endif
10447#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010448 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010449#endif
10450#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010451 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010452#endif
10453#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010454 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010455#endif
10456#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010457 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010458#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010459 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010460#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010461 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10462 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10463#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010464#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010465#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010467#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010468#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010470#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010471#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010473#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010474#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010476#endif /* HAVE_GETEUID */
10477#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010479#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010480#ifdef HAVE_GETGROUPLIST
10481 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10482#endif
Fred Drakec9680921999-12-13 16:37:25 +000010483#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010485#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010487#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010489#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010490#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010492#endif /* HAVE_GETPPID */
10493#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010495#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010496#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010497 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010498#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010499#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010500 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010501#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010502#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010503 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010504#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010505#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010506 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010507#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010508#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10510 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010511#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010512#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010514#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010515#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010517#endif /* HAVE_SETEUID */
10518#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010520#endif /* HAVE_SETEGID */
10521#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010523#endif /* HAVE_SETREUID */
10524#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010525 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000010526#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010527#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010529#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010530#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010531 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010532#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010533#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010534 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010535#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010536#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010538#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010539#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010540 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010541#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010542#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010544#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010545#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010010546 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010547#endif /* HAVE_WAIT3 */
10548#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010010549 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010550#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010551#if defined(HAVE_WAITID) && !defined(__APPLE__)
10552 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10553#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010554#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010556#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010557#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010558 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010559#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010560#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010561 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010562#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010563#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010564 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010565#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010566#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010567 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010568#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010569#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010570 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010571#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010572 {"open", (PyCFunction)posix_open,\
10573 METH_VARARGS | METH_KEYWORDS,
10574 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10576 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10577 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10578 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10579 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010580#ifdef HAVE_LOCKF
10581 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10582#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010583 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10584 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010585#ifdef HAVE_READV
10586 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10587#endif
10588#ifdef HAVE_PREAD
10589 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10590#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010591 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010592#ifdef HAVE_WRITEV
10593 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10594#endif
10595#ifdef HAVE_PWRITE
10596 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10597#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010598#ifdef HAVE_SENDFILE
10599 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10600 posix_sendfile__doc__},
10601#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010010602 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010604#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010606#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010607#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010608 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010609#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010610#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070010611 {"mkfifo", (PyCFunction)posix_mkfifo,
10612 METH_VARARGS | METH_KEYWORDS,
10613 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010614#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010615#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010616 {"mknod", (PyCFunction)posix_mknod,
10617 METH_VARARGS | METH_KEYWORDS,
10618 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010619#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010620#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10622 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10623 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010624#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010625#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010626 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010627#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010628#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020010629 {"truncate", (PyCFunction)posix_truncate,
10630 METH_VARARGS | METH_KEYWORDS,
10631 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010632#endif
10633#ifdef HAVE_POSIX_FALLOCATE
10634 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10635#endif
10636#ifdef HAVE_POSIX_FADVISE
10637 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10638#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010639#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010640 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010641#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010642#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010643 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010644#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010646#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010647 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010648#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010649#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010651#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010652#ifdef HAVE_SYNC
10653 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10654#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010655#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010657#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010658#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010659#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010660 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010661#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010662#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010663 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010664#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010665#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010667#endif /* WIFSTOPPED */
10668#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010670#endif /* WIFSIGNALED */
10671#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010673#endif /* WIFEXITED */
10674#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010676#endif /* WEXITSTATUS */
10677#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010679#endif /* WTERMSIG */
10680#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010681 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010682#endif /* WSTOPSIG */
10683#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010684#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010686#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010687#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010688 {"statvfs", (PyCFunction)posix_statvfs,
10689 METH_VARARGS | METH_KEYWORDS,
10690 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010691#endif
Fred Drakec9680921999-12-13 16:37:25 +000010692#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010693 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010694#endif
10695#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010697#endif
10698#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010699 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010700#endif
10701#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020010702 {"pathconf", (PyCFunction)posix_pathconf,
10703 METH_VARARGS | METH_KEYWORDS,
10704 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010705#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010707#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010709 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010710 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010711 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010712#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010713#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010715#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010010716 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010717#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010719#endif
10720#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010722#endif
10723#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010724 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010725#endif
10726#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010728#endif
10729
Benjamin Peterson9428d532011-09-14 11:45:52 -040010730#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010731 {"setxattr", (PyCFunction)posix_setxattr,
10732 METH_VARARGS | METH_KEYWORDS,
10733 posix_setxattr__doc__},
10734 {"getxattr", (PyCFunction)posix_getxattr,
10735 METH_VARARGS | METH_KEYWORDS,
10736 posix_getxattr__doc__},
10737 {"removexattr", (PyCFunction)posix_removexattr,
10738 METH_VARARGS | METH_KEYWORDS,
10739 posix_removexattr__doc__},
10740 {"listxattr", (PyCFunction)posix_listxattr,
10741 METH_VARARGS | METH_KEYWORDS,
10742 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040010743#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010744#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10745 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
10746#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010748};
10749
10750
Barry Warsaw4a342091996-12-19 23:50:02 +000010751static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010752ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010753{
Victor Stinner8c62be82010-05-06 00:08:46 +000010754 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010755}
10756
Brian Curtin52173d42010-12-02 18:29:18 +000010757#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010758static int
Brian Curtin52173d42010-12-02 18:29:18 +000010759enable_symlink()
10760{
10761 HANDLE tok;
10762 TOKEN_PRIVILEGES tok_priv;
10763 LUID luid;
10764 int meth_idx = 0;
10765
10766 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010767 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010768
10769 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010770 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010771
10772 tok_priv.PrivilegeCount = 1;
10773 tok_priv.Privileges[0].Luid = luid;
10774 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
10775
10776 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
10777 sizeof(TOKEN_PRIVILEGES),
10778 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000010779 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000010780
Brian Curtin3b4499c2010-12-28 14:31:47 +000010781 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
10782 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000010783}
10784#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
10785
Barry Warsaw4a342091996-12-19 23:50:02 +000010786static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000010787all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000010788{
Guido van Rossum94f6f721999-01-06 18:42:14 +000010789#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010791#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010792#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010794#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010795#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010797#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000010798#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010799 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010800#endif
Fred Drakec9680921999-12-13 16:37:25 +000010801#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000010803#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010804#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010806#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010807#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010809#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010810#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010812#endif
Fred Drake106c1a02002-04-23 15:58:02 +000010813#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000010815#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000010816#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010817 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010818#endif
10819#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000010820 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010821#endif
10822#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000010823 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010824#endif
10825#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000010826 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010827#endif
10828#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010829 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010830#endif
10831#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000010832 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010833#endif
10834#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010836#endif
10837#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010838 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010839#endif
10840#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010841 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010842#endif
10843#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010845#endif
10846#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010848#endif
10849#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010851#endif
10852#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000010854#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000010855#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010857#endif
10858#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000010860#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010861#ifdef O_XATTR
10862 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
10863#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010864#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010865 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010866#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000010867#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010869#endif
10870#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010871 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000010872#endif
Jesus Ceacf381202012-04-24 20:44:40 +020010873#ifdef O_EXEC
10874 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
10875#endif
10876#ifdef O_SEARCH
10877 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
10878#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050010879#ifdef O_PATH
10880 if (ins(d, "O_PATH", (long)O_PATH)) return -1;
10881#endif
Jesus Ceacf381202012-04-24 20:44:40 +020010882#ifdef O_TTY_INIT
10883 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
10884#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010885#ifdef PRIO_PROCESS
10886 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
10887#endif
10888#ifdef PRIO_PGRP
10889 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
10890#endif
10891#ifdef PRIO_USER
10892 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
10893#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020010894#ifdef O_CLOEXEC
10895 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
10896#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010897#ifdef O_ACCMODE
10898 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
10899#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010900
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010901
Jesus Cea94363612012-06-22 18:32:07 +020010902#ifdef SEEK_HOLE
10903 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
10904#endif
10905#ifdef SEEK_DATA
10906 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
10907#endif
10908
Tim Peters5aa91602002-01-30 05:46:57 +000010909/* MS Windows */
10910#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010911 /* Don't inherit in child processes. */
10912 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010913#endif
10914#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 /* Optimize for short life (keep in memory). */
10916 /* MS forgot to define this one with a non-underscore form too. */
10917 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010918#endif
10919#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 /* Automatically delete when last handle is closed. */
10921 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010922#endif
10923#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 /* Optimize for random access. */
10925 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010926#endif
10927#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 /* Optimize for sequential access. */
10929 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000010930#endif
10931
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010932/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010933#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010934 /* Send a SIGIO signal whenever input or output
10935 becomes available on file descriptor */
10936 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000010937#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010938#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 /* Direct disk access. */
10940 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010941#endif
10942#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000010943 /* Must be a directory. */
10944 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010945#endif
10946#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 /* Do not follow links. */
10948 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000010949#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020010950#ifdef O_NOLINKS
10951 /* Fails if link count of the named file is greater than 1 */
10952 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
10953#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010954#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010955 /* Do not update the access time. */
10956 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000010957#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000010958
Victor Stinner8c62be82010-05-06 00:08:46 +000010959 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010960#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010962#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010963#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010965#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010966#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010968#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010969#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010971#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010972#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010974#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010975#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010977#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010978#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010980#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010981#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010983#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010984#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010985 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010986#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010987#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000010988 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010989#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010990#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000010991 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010992#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010993#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000010994 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010995#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010996#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000010997 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000010998#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000010999#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011000 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011001#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011002#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011003 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011004#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011005#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011006 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011007#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011008#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011009 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011010#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011011
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011012 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011013#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011014 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011015#endif /* ST_RDONLY */
11016#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011017 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011018#endif /* ST_NOSUID */
11019
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011020 /* FreeBSD sendfile() constants */
11021#ifdef SF_NODISKIO
11022 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11023#endif
11024#ifdef SF_MNOWAIT
11025 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11026#endif
11027#ifdef SF_SYNC
11028 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11029#endif
11030
Ross Lagerwall7807c352011-03-17 20:20:30 +020011031 /* constants for posix_fadvise */
11032#ifdef POSIX_FADV_NORMAL
11033 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11034#endif
11035#ifdef POSIX_FADV_SEQUENTIAL
11036 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11037#endif
11038#ifdef POSIX_FADV_RANDOM
11039 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11040#endif
11041#ifdef POSIX_FADV_NOREUSE
11042 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11043#endif
11044#ifdef POSIX_FADV_WILLNEED
11045 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11046#endif
11047#ifdef POSIX_FADV_DONTNEED
11048 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11049#endif
11050
11051 /* constants for waitid */
11052#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11053 if (ins(d, "P_PID", (long)P_PID)) return -1;
11054 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11055 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11056#endif
11057#ifdef WEXITED
11058 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11059#endif
11060#ifdef WNOWAIT
11061 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11062#endif
11063#ifdef WSTOPPED
11064 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11065#endif
11066#ifdef CLD_EXITED
11067 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11068#endif
11069#ifdef CLD_DUMPED
11070 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11071#endif
11072#ifdef CLD_TRAPPED
11073 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11074#endif
11075#ifdef CLD_CONTINUED
11076 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11077#endif
11078
11079 /* constants for lockf */
11080#ifdef F_LOCK
11081 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11082#endif
11083#ifdef F_TLOCK
11084 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11085#endif
11086#ifdef F_ULOCK
11087 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11088#endif
11089#ifdef F_TEST
11090 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11091#endif
11092
Guido van Rossum246bc171999-02-01 23:54:31 +000011093#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011094 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11095 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11096 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11097 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11098 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011099#endif
11100
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011101#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011102 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011103 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11104 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11105#ifdef SCHED_SPORADIC
11106 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11107#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011108#ifdef SCHED_BATCH
11109 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11110#endif
11111#ifdef SCHED_IDLE
11112 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11113#endif
11114#ifdef SCHED_RESET_ON_FORK
11115 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11116#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011117#ifdef SCHED_SYS
11118 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11119#endif
11120#ifdef SCHED_IA
11121 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11122#endif
11123#ifdef SCHED_FSS
11124 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11125#endif
11126#ifdef SCHED_FX
11127 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11128#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011129#endif
11130
Benjamin Peterson9428d532011-09-14 11:45:52 -040011131#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011132 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11133 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11134 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11135#endif
11136
Victor Stinner8b905bd2011-10-25 13:34:04 +020011137#ifdef RTLD_LAZY
11138 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11139#endif
11140#ifdef RTLD_NOW
11141 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11142#endif
11143#ifdef RTLD_GLOBAL
11144 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11145#endif
11146#ifdef RTLD_LOCAL
11147 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11148#endif
11149#ifdef RTLD_NODELETE
11150 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11151#endif
11152#ifdef RTLD_NOLOAD
11153 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11154#endif
11155#ifdef RTLD_DEEPBIND
11156 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11157#endif
11158
Victor Stinner8c62be82010-05-06 00:08:46 +000011159 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011160}
11161
11162
Tim Peters5aa91602002-01-30 05:46:57 +000011163#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011164#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011165#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011166
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011167#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011168#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011169#define MODNAME "posix"
11170#endif
11171
Martin v. Löwis1a214512008-06-11 05:26:20 +000011172static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 PyModuleDef_HEAD_INIT,
11174 MODNAME,
11175 posix__doc__,
11176 -1,
11177 posix_methods,
11178 NULL,
11179 NULL,
11180 NULL,
11181 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011182};
11183
11184
Larry Hastings9cf065c2012-06-22 16:30:09 -070011185static char *have_functions[] = {
11186
11187#ifdef HAVE_FACCESSAT
11188 "HAVE_FACCESSAT",
11189#endif
11190
11191#ifdef HAVE_FCHDIR
11192 "HAVE_FCHDIR",
11193#endif
11194
11195#ifdef HAVE_FCHMOD
11196 "HAVE_FCHMOD",
11197#endif
11198
11199#ifdef HAVE_FCHMODAT
11200 "HAVE_FCHMODAT",
11201#endif
11202
11203#ifdef HAVE_FCHOWN
11204 "HAVE_FCHOWN",
11205#endif
11206
11207#ifdef HAVE_FEXECVE
11208 "HAVE_FEXECVE",
11209#endif
11210
11211#ifdef HAVE_FDOPENDIR
11212 "HAVE_FDOPENDIR",
11213#endif
11214
Georg Brandl306336b2012-06-24 12:55:33 +020011215#ifdef HAVE_FPATHCONF
11216 "HAVE_FPATHCONF",
11217#endif
11218
Larry Hastings9cf065c2012-06-22 16:30:09 -070011219#ifdef HAVE_FSTATAT
11220 "HAVE_FSTATAT",
11221#endif
11222
11223#ifdef HAVE_FSTATVFS
11224 "HAVE_FSTATVFS",
11225#endif
11226
Georg Brandl306336b2012-06-24 12:55:33 +020011227#ifdef HAVE_FTRUNCATE
11228 "HAVE_FTRUNCATE",
11229#endif
11230
Larry Hastings9cf065c2012-06-22 16:30:09 -070011231#ifdef HAVE_FUTIMENS
11232 "HAVE_FUTIMENS",
11233#endif
11234
11235#ifdef HAVE_FUTIMES
11236 "HAVE_FUTIMES",
11237#endif
11238
11239#ifdef HAVE_FUTIMESAT
11240 "HAVE_FUTIMESAT",
11241#endif
11242
11243#ifdef HAVE_LINKAT
11244 "HAVE_LINKAT",
11245#endif
11246
11247#ifdef HAVE_LCHFLAGS
11248 "HAVE_LCHFLAGS",
11249#endif
11250
11251#ifdef HAVE_LCHMOD
11252 "HAVE_LCHMOD",
11253#endif
11254
11255#ifdef HAVE_LCHOWN
11256 "HAVE_LCHOWN",
11257#endif
11258
11259#ifdef HAVE_LSTAT
11260 "HAVE_LSTAT",
11261#endif
11262
11263#ifdef HAVE_LUTIMES
11264 "HAVE_LUTIMES",
11265#endif
11266
11267#ifdef HAVE_MKDIRAT
11268 "HAVE_MKDIRAT",
11269#endif
11270
11271#ifdef HAVE_MKFIFOAT
11272 "HAVE_MKFIFOAT",
11273#endif
11274
11275#ifdef HAVE_MKNODAT
11276 "HAVE_MKNODAT",
11277#endif
11278
11279#ifdef HAVE_OPENAT
11280 "HAVE_OPENAT",
11281#endif
11282
11283#ifdef HAVE_READLINKAT
11284 "HAVE_READLINKAT",
11285#endif
11286
11287#ifdef HAVE_RENAMEAT
11288 "HAVE_RENAMEAT",
11289#endif
11290
11291#ifdef HAVE_SYMLINKAT
11292 "HAVE_SYMLINKAT",
11293#endif
11294
11295#ifdef HAVE_UNLINKAT
11296 "HAVE_UNLINKAT",
11297#endif
11298
11299#ifdef HAVE_UTIMENSAT
11300 "HAVE_UTIMENSAT",
11301#endif
11302
11303#ifdef MS_WINDOWS
11304 "MS_WINDOWS",
11305#endif
11306
11307 NULL
11308};
11309
11310
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011311PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011312INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011313{
Victor Stinner8c62be82010-05-06 00:08:46 +000011314 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011315 PyObject *list;
11316 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011317
Brian Curtin52173d42010-12-02 18:29:18 +000011318#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011319 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011320#endif
11321
Victor Stinner8c62be82010-05-06 00:08:46 +000011322 m = PyModule_Create(&posixmodule);
11323 if (m == NULL)
11324 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011325
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 /* Initialize environ dictionary */
11327 v = convertenviron();
11328 Py_XINCREF(v);
11329 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11330 return NULL;
11331 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011332
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 if (all_ins(m))
11334 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011335
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 if (setup_confname_tables(m))
11337 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011338
Victor Stinner8c62be82010-05-06 00:08:46 +000011339 Py_INCREF(PyExc_OSError);
11340 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011341
Guido van Rossumb3d39562000-01-31 18:41:26 +000011342#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011343 if (posix_putenv_garbage == NULL)
11344 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011345#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011346
Victor Stinner8c62be82010-05-06 00:08:46 +000011347 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011348#if defined(HAVE_WAITID) && !defined(__APPLE__)
11349 waitid_result_desc.name = MODNAME ".waitid_result";
11350 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11351#endif
11352
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 stat_result_desc.name = MODNAME ".stat_result";
11354 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11355 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11356 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11357 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11358 structseq_new = StatResultType.tp_new;
11359 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011360
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 statvfs_result_desc.name = MODNAME ".statvfs_result";
11362 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011363#ifdef NEED_TICKS_PER_SECOND
11364# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011365 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011366# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011368# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011370# endif
11371#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011372
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011373#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011374 sched_param_desc.name = MODNAME ".sched_param";
11375 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11376 SchedParamType.tp_new = sched_param_new;
11377#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011378
11379 /* initialize TerminalSize_info */
11380 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011382#if defined(HAVE_WAITID) && !defined(__APPLE__)
11383 Py_INCREF((PyObject*) &WaitidResultType);
11384 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11385#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011386 Py_INCREF((PyObject*) &StatResultType);
11387 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11388 Py_INCREF((PyObject*) &StatVFSResultType);
11389 PyModule_AddObject(m, "statvfs_result",
11390 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011391
11392#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011393 Py_INCREF(&SchedParamType);
11394 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011395#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011396
Larry Hastings605a62d2012-06-24 04:33:36 -070011397 times_result_desc.name = MODNAME ".times_result";
11398 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11399 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11400
11401 uname_result_desc.name = MODNAME ".uname_result";
11402 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11403 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11404
Thomas Wouters477c8d52006-05-27 19:21:47 +000011405#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011406 /*
11407 * Step 2 of weak-linking support on Mac OS X.
11408 *
11409 * The code below removes functions that are not available on the
11410 * currently active platform.
11411 *
11412 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011413 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 * OSX 10.4.
11415 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011416#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 if (fstatvfs == NULL) {
11418 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11419 return NULL;
11420 }
11421 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011422#endif /* HAVE_FSTATVFS */
11423
11424#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011425 if (statvfs == NULL) {
11426 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11427 return NULL;
11428 }
11429 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011430#endif /* HAVE_STATVFS */
11431
11432# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 if (lchown == NULL) {
11434 if (PyObject_DelAttrString(m, "lchown") == -1) {
11435 return NULL;
11436 }
11437 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011438#endif /* HAVE_LCHOWN */
11439
11440
11441#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011442
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020011443 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011444 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
11445
Larry Hastings6fe20b32012-04-19 15:07:49 -070011446 billion = PyLong_FromLong(1000000000);
11447 if (!billion)
11448 return NULL;
11449
Larry Hastings9cf065c2012-06-22 16:30:09 -070011450 /* suppress "function not used" warnings */
11451 {
11452 int ignored;
11453 fd_specified("", -1);
11454 follow_symlinks_specified("", 1);
11455 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
11456 dir_fd_converter(Py_None, &ignored);
11457 dir_fd_unavailable(Py_None, &ignored);
11458 }
11459
11460 /*
11461 * provide list of locally available functions
11462 * so os.py can populate support_* lists
11463 */
11464 list = PyList_New(0);
11465 if (!list)
11466 return NULL;
11467 for (trace = have_functions; *trace; trace++) {
11468 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
11469 if (!unicode)
11470 return NULL;
11471 if (PyList_Append(list, unicode))
11472 return NULL;
11473 Py_DECREF(unicode);
11474 }
11475 PyModule_AddObject(m, "_have_functions", list);
11476
11477 initialized = 1;
11478
Victor Stinner8c62be82010-05-06 00:08:46 +000011479 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011480
Guido van Rossumb6775db1994-08-01 11:34:53 +000011481}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011482
11483#ifdef __cplusplus
11484}
11485#endif