blob: d38a4dbefd7489c467da1c193592ba4db94d88b3 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Thomas Wouters477c8d52006-05-27 19:21:47 +000016#ifdef __APPLE__
17 /*
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#if defined(PYOS_OS2)
49#define INCL_DOS
50#define INCL_DOSERRORS
51#define INCL_DOSPROCESS
52#define INCL_NOPMAPI
53#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000054#if defined(PYCC_GCC)
55#include <ctype.h>
56#include <io.h>
57#include <stdio.h>
58#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000059#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000060#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#endif
62
Thomas Wouters0e3f5912006-08-11 14:57:12 +000063#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#endif /* HAVE_SYS_TYPES_H */
66
67#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070
Guido van Rossum36bc6801995-06-14 22:54:23 +000071#ifdef HAVE_SYS_WAIT_H
72#include <sys/wait.h> /* For WNOHANG */
73#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000076#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000078
Guido van Rossumb6775db1994-08-01 11:34:53 +000079#ifdef HAVE_FCNTL_H
80#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000081#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
Guido van Rossuma6535fd2001-10-18 19:44:10 +000083#ifdef HAVE_GRP_H
84#include <grp.h>
85#endif
86
Barry Warsaw5676bd12003-01-07 20:57:09 +000087#ifdef HAVE_SYSEXITS_H
88#include <sysexits.h>
89#endif /* HAVE_SYSEXITS_H */
90
Anthony Baxter8a560de2004-10-13 15:30:56 +000091#ifdef HAVE_SYS_LOADAVG_H
92#include <sys/loadavg.h>
93#endif
94
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000095#ifdef HAVE_LANGINFO_H
96#include <langinfo.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
107#define HAVE_SYSTEM 1
108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
114#ifdef __BORLANDC__ /* Borland compiler */
115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000119#define HAVE_SYSTEM 1
120#define HAVE_WAIT 1
121#else
122#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000123#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000124#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#define HAVE_EXECV 1
126#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000128#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000129#define HAVE_FSYNC 1
130#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000131#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000132#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
133/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#else /* all other compilers */
135/* Unix functions that the configure script doesn't check for */
136#define HAVE_EXECV 1
137#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000138#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
139#define HAVE_FORK1 1
140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#define HAVE_GETCWD 1
142#define HAVE_GETEGID 1
143#define HAVE_GETEUID 1
144#define HAVE_GETGID 1
145#define HAVE_GETPPID 1
146#define HAVE_GETUID 1
147#define HAVE_KILL 1
148#define HAVE_OPENDIR 1
149#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_SYSTEM 1
151#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000152#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000153#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#endif /* _MSC_VER */
155#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000156#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000157#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000158
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000160
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000161#if defined(__sgi)&&_COMPILER_VERSION>=700
162/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
163 (default) */
164extern char *ctermid_r(char *);
165#endif
166
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000167#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000168#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000170#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000171#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000176#endif
177#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int chdir(char *);
179extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000180#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int chdir(const char *);
182extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000183#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000184#ifdef __BORLANDC__
185extern int chmod(const char *, int);
186#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000188#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000189/*#ifdef HAVE_FCHMOD
190extern int fchmod(int, mode_t);
191#endif*/
192/*#ifdef HAVE_LCHMOD
193extern int lchmod(const char *, mode_t);
194#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int chown(const char *, uid_t, gid_t);
196extern char *getcwd(char *, int);
197extern char *strerror(int);
198extern int link(const char *, const char *);
199extern int rename(const char *, const char *);
200extern int stat(const char *, struct stat *);
201extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000204#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_UTIME_H
213#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000216#ifdef HAVE_SYS_UTIME_H
217#include <sys/utime.h>
218#define HAVE_UTIME_H /* pretend we do for the rest of this file */
219#endif /* HAVE_SYS_UTIME_H */
220
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#ifdef HAVE_SYS_TIMES_H
222#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
225#ifdef HAVE_SYS_PARAM_H
226#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
229#ifdef HAVE_SYS_UTSNAME_H
230#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) strlen((dirent)->d_name)
236#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000237#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#include <direct.h>
239#define NAMLEN(dirent) strlen((dirent)->d_name)
240#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000243#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#endif
250#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000264#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000265#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000266#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000268#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270
Guido van Rossumd48f2521997-12-05 22:19:34 +0000271#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274
Tim Petersbc2e10e2002-03-03 23:17:02 +0000275#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000276#if defined(PATH_MAX) && PATH_MAX > 1024
277#define MAXPATHLEN PATH_MAX
278#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000279#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000280#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000281#endif /* MAXPATHLEN */
282
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000283#ifdef UNION_WAIT
284/* Emulate some macros on systems that have a union instead of macros */
285
286#ifndef WIFEXITED
287#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
288#endif
289
290#ifndef WEXITSTATUS
291#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
292#endif
293
294#ifndef WTERMSIG
295#define WTERMSIG(u_wait) ((u_wait).w_termsig)
296#endif
297
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000298#define WAIT_TYPE union wait
299#define WAIT_STATUS_INT(s) (s.w_status)
300
301#else /* !UNION_WAIT */
302#define WAIT_TYPE int
303#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000304#endif /* UNION_WAIT */
305
Greg Wardb48bc172000-03-01 21:51:56 +0000306/* Don't use the "_r" form if we don't need it (also, won't have a
307 prototype for it, at least on Solaris -- maybe others as well?). */
308#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
309#define USE_CTERMID_R
310#endif
311
Fred Drake699f3522000-06-29 21:12:41 +0000312/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000313#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000314#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000315# define STAT win32_stat
316# define FSTAT win32_fstat
317# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000318#else
319# define STAT stat
320# define FSTAT fstat
321# define STRUCT_STAT struct stat
322#endif
323
Tim Peters11b23062003-04-23 02:39:17 +0000324#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000325#include <sys/mkdev.h>
326#else
327#if defined(MAJOR_IN_SYSMACROS)
328#include <sys/sysmacros.h>
329#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000330#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
331#include <sys/mkdev.h>
332#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000333#endif
Fred Drake699f3522000-06-29 21:12:41 +0000334
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000335#if defined _MSC_VER && _MSC_VER >= 1400
336/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
337 * valid and throw an assertion if it isn't.
338 * Normally, an invalid fd is likely to be a C program error and therefore
339 * an assertion can be useful, but it does contradict the POSIX standard
340 * which for write(2) states:
341 * "Otherwise, -1 shall be returned and errno set to indicate the error."
342 * "[EBADF] The fildes argument is not a valid file descriptor open for
343 * writing."
344 * Furthermore, python allows the user to enter any old integer
345 * as a fd and should merely raise a python exception on error.
346 * The Microsoft CRT doesn't provide an official way to check for the
347 * validity of a file descriptor, but we can emulate its internal behaviour
348 * by using the exported __pinfo data member and knowledge of the
349 * internal structures involved.
350 * The structures below must be updated for each version of visual studio
351 * according to the file internal.h in the CRT source, until MS comes
352 * up with a less hacky way to do this.
353 * (all of this is to avoid globally modifying the CRT behaviour using
354 * _set_invalid_parameter_handler() and _CrtSetReportMode())
355 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000356/* The actual size of the structure is determined at runtime.
357 * Only the first items must be present.
358 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000359typedef struct {
360 intptr_t osfhnd;
361 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000362} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000363
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000364extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000365#define IOINFO_L2E 5
366#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
367#define IOINFO_ARRAYS 64
368#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
369#define FOPEN 0x01
370#define _NO_CONSOLE_FILENO (intptr_t)-2
371
372/* This function emulates what the windows CRT does to validate file handles */
373int
374_PyVerify_fd(int fd)
375{
376 const int i1 = fd >> IOINFO_L2E;
377 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000378
379 static int sizeof_ioinfo = 0;
380
381 /* Determine the actual size of the ioinfo structure,
382 * as used by the CRT loaded in memory
383 */
384 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
385 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
386 }
387 if (sizeof_ioinfo == 0) {
388 /* This should not happen... */
389 goto fail;
390 }
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000391
392 /* See that it isn't a special CLEAR fileno */
393 if (fd != _NO_CONSOLE_FILENO) {
394 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
395 * we check pointer validity and other info
396 */
397 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
398 /* finally, check that the file is open */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000399 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
400 if (info->osfile & FOPEN) {
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000401 return 1;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000402 }
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000403 }
404 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000405 fail:
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000406 errno = EBADF;
407 return 0;
408}
409
410/* the special case of checking dup2. The target fd must be in a sensible range */
411static int
412_PyVerify_fd_dup2(int fd1, int fd2)
413{
414 if (!_PyVerify_fd(fd1))
415 return 0;
416 if (fd2 == _NO_CONSOLE_FILENO)
417 return 0;
418 if ((unsigned)fd2 < _NHANDLE_)
419 return 1;
420 else
421 return 0;
422}
423#else
424/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
425#define _PyVerify_fd_dup2(A, B) (1)
426#endif
427
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000428/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000429#ifdef WITH_NEXT_FRAMEWORK
430/* On Darwin/MacOSX a shared library or framework has no access to
431** environ directly, we must obtain it with _NSGetEnviron().
432*/
433#include <crt_externs.h>
434static char **environ;
435#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000436extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000437#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000438
Barry Warsaw53699e91996-12-10 23:23:01 +0000439static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000440convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000441{
Barry Warsaw53699e91996-12-10 23:23:01 +0000442 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000443#ifdef MS_WINDOWS
444 wchar_t **e;
445#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000446 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000447#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000448 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000449 if (d == NULL)
450 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000451#ifdef WITH_NEXT_FRAMEWORK
452 if (environ == NULL)
453 environ = *_NSGetEnviron();
454#endif
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000455#ifdef MS_WINDOWS
456 /* _wenviron must be initialized in this way if the program is started
457 through main() instead of wmain(). */
458 _wgetenv(L"");
459 if (_wenviron == NULL)
460 return d;
461 /* This part ignores errors */
462 for (e = _wenviron; *e != NULL; e++) {
463 PyObject *k;
464 PyObject *v;
465 wchar_t *p = wcschr(*e, L'=');
466 if (p == NULL)
467 continue;
468 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
469 if (k == NULL) {
470 PyErr_Clear();
471 continue;
472 }
473 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
474 if (v == NULL) {
475 PyErr_Clear();
476 Py_DECREF(k);
477 continue;
478 }
479 if (PyDict_GetItem(d, k) == NULL) {
480 if (PyDict_SetItem(d, k, v) != 0)
481 PyErr_Clear();
482 }
483 Py_DECREF(k);
484 Py_DECREF(v);
485 }
486#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487 if (environ == NULL)
488 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000489 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000490 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000491 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000492 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000493 char *p = strchr(*e, '=');
494 if (p == NULL)
495 continue;
Martin v. Löwis011e8422009-05-05 04:43:17 +0000496 k = PyUnicode_Decode(*e, (int)(p-*e),
497 Py_FileSystemDefaultEncoding, "utf8b");
Guido van Rossum6a619f41999-08-03 19:41:10 +0000498 if (k == NULL) {
499 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000501 }
Martin v. Löwis011e8422009-05-05 04:43:17 +0000502 v = PyUnicode_Decode(p+1, strlen(p+1),
503 Py_FileSystemDefaultEncoding, "utf8b");
Guido van Rossum6a619f41999-08-03 19:41:10 +0000504 if (v == NULL) {
505 PyErr_Clear();
506 Py_DECREF(k);
507 continue;
508 }
509 if (PyDict_GetItem(d, k) == NULL) {
510 if (PyDict_SetItem(d, k, v) != 0)
511 PyErr_Clear();
512 }
513 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000514 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000515 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000516#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000517#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000518 {
519 APIRET rc;
520 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
521
522 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000523 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000524 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000525 PyDict_SetItemString(d, "BEGINLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000526 Py_DECREF(v);
527 }
528 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
529 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000530 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000531 PyDict_SetItemString(d, "ENDLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000532 Py_DECREF(v);
533 }
534 }
535#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000536 return d;
537}
538
Martin v. Löwis011e8422009-05-05 04:43:17 +0000539/* Convert a bytes object to a char*. Optionally lock the buffer if it is a
540 bytes array. */
541
542static char*
543bytes2str(PyObject* o, int lock)
544{
545 if(PyBytes_Check(o))
546 return PyBytes_AsString(o);
547 else if(PyByteArray_Check(o)) {
548 if (lock && PyObject_GetBuffer(o, NULL, 0) < 0)
549 /* On a bytearray, this should not fail. */
550 PyErr_BadInternalCall();
551 return PyByteArray_AsString(o);
552 } else {
553 /* The FS converter should have verified that this
554 is either bytes or bytearray. */
555 Py_FatalError("bad object passed to bytes2str");
556 /* not reached. */
557 return "";
558 }
559}
560
561/* Release the lock, decref the object. */
562static void
563release_bytes(PyObject* o)
564{
565 if (PyByteArray_Check(o))
566 o->ob_type->tp_as_buffer->bf_releasebuffer(NULL, 0);
567 Py_DECREF(o);
568}
569
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000570
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000571/* Set a POSIX-specific error from errno, and return NULL */
572
Barry Warsawd58d7641998-07-23 16:14:40 +0000573static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000574posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000575{
Barry Warsawca74da41999-02-09 19:31:45 +0000576 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000577}
Barry Warsawd58d7641998-07-23 16:14:40 +0000578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000579posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000580{
Barry Warsawca74da41999-02-09 19:31:45 +0000581 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000582}
583
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000584#ifdef Py_WIN_WIDE_FILENAMES
585static PyObject *
586posix_error_with_unicode_filename(Py_UNICODE* name)
587{
588 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
589}
590#endif /* Py_WIN_WIDE_FILENAMES */
591
592
Mark Hammondef8b6542001-05-13 08:04:26 +0000593static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000594posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000595{
Martin v. Löwis011e8422009-05-05 04:43:17 +0000596 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError,
597 bytes2str(name, 0));
598 release_bytes(name);
Mark Hammondef8b6542001-05-13 08:04:26 +0000599 return rc;
600}
601
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000602#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000603static PyObject *
604win32_error(char* function, char* filename)
605{
Mark Hammond33a6da92000-08-15 00:46:38 +0000606 /* XXX We should pass the function name along in the future.
Georg Brandl38feaf02008-05-25 07:45:51 +0000607 (winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000608 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000609 Windows error object, which is non-trivial.
610 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000611 errno = GetLastError();
612 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000613 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000614 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000615 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000616}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000617
618#ifdef Py_WIN_WIDE_FILENAMES
619static PyObject *
620win32_error_unicode(char* function, Py_UNICODE* filename)
621{
622 /* XXX - see win32_error for comments on 'function' */
623 errno = GetLastError();
624 if (filename)
625 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
626 else
627 return PyErr_SetFromWindowsErr(errno);
628}
629
Thomas Wouters477c8d52006-05-27 19:21:47 +0000630static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000631convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000632{
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000633 if (PyUnicode_CheckExact(*param))
634 Py_INCREF(*param);
635 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000636 /* For a Unicode subtype that's not a Unicode object,
637 return a true Unicode object with the same data. */
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000638 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
639 PyUnicode_GET_SIZE(*param));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000640 else
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000641 *param = PyUnicode_FromEncodedObject(*param,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000642 Py_FileSystemDefaultEncoding,
643 "strict");
644 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000645}
646
647#endif /* Py_WIN_WIDE_FILENAMES */
648
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000649#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000650
Guido van Rossumd48f2521997-12-05 22:19:34 +0000651#if defined(PYOS_OS2)
652/**********************************************************************
653 * Helper Function to Trim and Format OS/2 Messages
654 **********************************************************************/
655 static void
656os2_formatmsg(char *msgbuf, int msglen, char *reason)
657{
658 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
659
660 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
661 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
662
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000663 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000664 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
665 }
666
667 /* Add Optional Reason Text */
668 if (reason) {
669 strcat(msgbuf, " : ");
670 strcat(msgbuf, reason);
671 }
672}
673
674/**********************************************************************
675 * Decode an OS/2 Operating System Error Code
676 *
677 * A convenience function to lookup an OS/2 error code and return a
678 * text message we can use to raise a Python exception.
679 *
680 * Notes:
681 * The messages for errors returned from the OS/2 kernel reside in
682 * the file OSO001.MSG in the \OS2 directory hierarchy.
683 *
684 **********************************************************************/
685 static char *
686os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
687{
688 APIRET rc;
689 ULONG msglen;
690
691 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
692 Py_BEGIN_ALLOW_THREADS
693 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
694 errorcode, "oso001.msg", &msglen);
695 Py_END_ALLOW_THREADS
696
697 if (rc == NO_ERROR)
698 os2_formatmsg(msgbuf, msglen, reason);
699 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000700 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000701 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000702
703 return msgbuf;
704}
705
706/* Set an OS/2-specific error and return NULL. OS/2 kernel
707 errors are not in a global variable e.g. 'errno' nor are
708 they congruent with posix error numbers. */
709
710static PyObject * os2_error(int code)
711{
712 char text[1024];
713 PyObject *v;
714
715 os2_strerror(text, sizeof(text), code, "");
716
717 v = Py_BuildValue("(is)", code, text);
718 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000719 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000720 Py_DECREF(v);
721 }
722 return NULL; /* Signal to Python that an Exception is Pending */
723}
724
725#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000726
727/* POSIX generic methods */
728
Barry Warsaw53699e91996-12-10 23:23:01 +0000729static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000730posix_fildes(PyObject *fdobj, int (*func)(int))
731{
732 int fd;
733 int res;
734 fd = PyObject_AsFileDescriptor(fdobj);
735 if (fd < 0)
736 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000737 if (!_PyVerify_fd(fd))
738 return posix_error();
Fred Drake4d1e64b2002-04-15 19:40:07 +0000739 Py_BEGIN_ALLOW_THREADS
740 res = (*func)(fd);
741 Py_END_ALLOW_THREADS
742 if (res < 0)
743 return posix_error();
744 Py_INCREF(Py_None);
745 return Py_None;
746}
Guido van Rossum21142a01999-01-08 21:05:37 +0000747
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000748#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000749static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000750unicode_file_names(void)
751{
752 static int canusewide = -1;
753 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000754 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000755 the Windows NT family. */
756 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
757 }
758 return canusewide;
759}
760#endif
Tim Peters11b23062003-04-23 02:39:17 +0000761
Guido van Rossum21142a01999-01-08 21:05:37 +0000762static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000763posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000764{
Martin v. Löwis011e8422009-05-05 04:43:17 +0000765 PyObject *opath1 = NULL;
766 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000767 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000768 if (!PyArg_ParseTuple(args, format,
Martin v. Löwis011e8422009-05-05 04:43:17 +0000769 PyUnicode_FSConverter, &opath1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000770 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +0000771 path1 = bytes2str(opath1, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000772 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000773 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000774 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000775 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +0000776 return posix_error_with_allocated_filename(opath1);
777 release_bytes(opath1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000778 Py_INCREF(Py_None);
779 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000780}
781
Barry Warsaw53699e91996-12-10 23:23:01 +0000782static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000783posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000784 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000785 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000786{
Martin v. Löwis011e8422009-05-05 04:43:17 +0000787 PyObject *opath1, *opath2;
788 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000789 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000790 if (!PyArg_ParseTuple(args, format,
Martin v. Löwis011e8422009-05-05 04:43:17 +0000791 PyUnicode_FSConverter, &opath1,
792 PyUnicode_FSConverter, &opath2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000793 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +0000794 path1 = bytes2str(opath1, 1);
795 path2 = bytes2str(opath2, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000796 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000797 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000798 Py_END_ALLOW_THREADS
Martin v. Löwis011e8422009-05-05 04:43:17 +0000799 release_bytes(opath1);
800 release_bytes(opath2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000801 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000802 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000803 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000804 Py_INCREF(Py_None);
805 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000806}
807
Thomas Wouters477c8d52006-05-27 19:21:47 +0000808#ifdef Py_WIN_WIDE_FILENAMES
809static PyObject*
810win32_1str(PyObject* args, char* func,
811 char* format, BOOL (__stdcall *funcA)(LPCSTR),
812 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
813{
814 PyObject *uni;
815 char *ansi;
816 BOOL result;
817 if (unicode_file_names()) {
818 if (!PyArg_ParseTuple(args, wformat, &uni))
819 PyErr_Clear();
820 else {
821 Py_BEGIN_ALLOW_THREADS
822 result = funcW(PyUnicode_AsUnicode(uni));
823 Py_END_ALLOW_THREADS
824 if (!result)
825 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
826 Py_INCREF(Py_None);
827 return Py_None;
828 }
829 }
830 if (!PyArg_ParseTuple(args, format, &ansi))
831 return NULL;
832 Py_BEGIN_ALLOW_THREADS
833 result = funcA(ansi);
834 Py_END_ALLOW_THREADS
835 if (!result)
836 return win32_error(func, ansi);
837 Py_INCREF(Py_None);
838 return Py_None;
839
840}
841
842/* This is a reimplementation of the C library's chdir function,
843 but one that produces Win32 errors instead of DOS error codes.
844 chdir is essentially a wrapper around SetCurrentDirectory; however,
845 it also needs to set "magic" environment variables indicating
846 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000847static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000848win32_chdir(LPCSTR path)
849{
850 char new_path[MAX_PATH+1];
851 int result;
852 char env[4] = "=x:";
853
854 if(!SetCurrentDirectoryA(path))
855 return FALSE;
856 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
857 if (!result)
858 return FALSE;
859 /* In the ANSI API, there should not be any paths longer
860 than MAX_PATH. */
861 assert(result <= MAX_PATH+1);
862 if (strncmp(new_path, "\\\\", 2) == 0 ||
863 strncmp(new_path, "//", 2) == 0)
864 /* UNC path, nothing to do. */
865 return TRUE;
866 env[1] = new_path[0];
867 return SetEnvironmentVariableA(env, new_path);
868}
869
870/* The Unicode version differs from the ANSI version
871 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000872static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000873win32_wchdir(LPCWSTR path)
874{
875 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
876 int result;
877 wchar_t env[4] = L"=x:";
878
879 if(!SetCurrentDirectoryW(path))
880 return FALSE;
881 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
882 if (!result)
883 return FALSE;
884 if (result > MAX_PATH+1) {
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000885 new_path = malloc(result * sizeof(wchar_t));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000886 if (!new_path) {
887 SetLastError(ERROR_OUTOFMEMORY);
888 return FALSE;
889 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000890 result = GetCurrentDirectoryW(result, new_path);
891 if (!result) {
892 free(new_path);
893 return FALSE;
894 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000895 }
896 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
897 wcsncmp(new_path, L"//", 2) == 0)
898 /* UNC path, nothing to do. */
899 return TRUE;
900 env[1] = new_path[0];
901 result = SetEnvironmentVariableW(env, new_path);
902 if (new_path != _new_path)
903 free(new_path);
904 return result;
905}
906#endif
907
Martin v. Löwis14694662006-02-03 12:54:16 +0000908#ifdef MS_WINDOWS
909/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
910 - time stamps are restricted to second resolution
911 - file modification times suffer from forth-and-back conversions between
912 UTC and local time
913 Therefore, we implement our own stat, based on the Win32 API directly.
914*/
915#define HAVE_STAT_NSEC 1
916
917struct win32_stat{
918 int st_dev;
919 __int64 st_ino;
920 unsigned short st_mode;
921 int st_nlink;
922 int st_uid;
923 int st_gid;
924 int st_rdev;
925 __int64 st_size;
926 int st_atime;
927 int st_atime_nsec;
928 int st_mtime;
929 int st_mtime_nsec;
930 int st_ctime;
931 int st_ctime_nsec;
932};
933
934static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
935
936static void
937FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
938{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000939 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
940 /* Cannot simply cast and dereference in_ptr,
941 since it might not be aligned properly */
942 __int64 in;
943 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000944 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
945 /* XXX Win32 supports time stamps past 2038; we currently don't */
946 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
947}
948
Thomas Wouters477c8d52006-05-27 19:21:47 +0000949static void
950time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
951{
952 /* XXX endianness */
953 __int64 out;
954 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000955 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000956 memcpy(out_ptr, &out, sizeof(out));
957}
958
Martin v. Löwis14694662006-02-03 12:54:16 +0000959/* Below, we *know* that ugo+r is 0444 */
960#if _S_IREAD != 0400
961#error Unsupported C library
962#endif
963static int
964attributes_to_mode(DWORD attr)
965{
966 int m = 0;
967 if (attr & FILE_ATTRIBUTE_DIRECTORY)
968 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
969 else
970 m |= _S_IFREG;
971 if (attr & FILE_ATTRIBUTE_READONLY)
972 m |= 0444;
973 else
974 m |= 0666;
975 return m;
976}
977
978static int
979attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
980{
981 memset(result, 0, sizeof(*result));
982 result->st_mode = attributes_to_mode(info->dwFileAttributes);
983 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
984 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
985 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
986 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
987
988 return 0;
989}
990
Thomas Wouters89f507f2006-12-13 04:49:30 +0000991/* Emulate GetFileAttributesEx[AW] on Windows 95 */
992static int checked = 0;
993static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
994static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
995static void
996check_gfax()
997{
998 HINSTANCE hKernel32;
999 if (checked)
1000 return;
1001 checked = 1;
1002 hKernel32 = GetModuleHandle("KERNEL32");
1003 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
1004 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
1005}
1006
Guido van Rossumd8faa362007-04-27 19:54:29 +00001007static BOOL
1008attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1009{
1010 HANDLE hFindFile;
1011 WIN32_FIND_DATAA FileData;
1012 hFindFile = FindFirstFileA(pszFile, &FileData);
1013 if (hFindFile == INVALID_HANDLE_VALUE)
1014 return FALSE;
1015 FindClose(hFindFile);
1016 pfad->dwFileAttributes = FileData.dwFileAttributes;
1017 pfad->ftCreationTime = FileData.ftCreationTime;
1018 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1019 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1020 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1021 pfad->nFileSizeLow = FileData.nFileSizeLow;
1022 return TRUE;
1023}
1024
1025static BOOL
1026attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1027{
1028 HANDLE hFindFile;
1029 WIN32_FIND_DATAW FileData;
1030 hFindFile = FindFirstFileW(pszFile, &FileData);
1031 if (hFindFile == INVALID_HANDLE_VALUE)
1032 return FALSE;
1033 FindClose(hFindFile);
1034 pfad->dwFileAttributes = FileData.dwFileAttributes;
1035 pfad->ftCreationTime = FileData.ftCreationTime;
1036 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1037 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1038 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1039 pfad->nFileSizeLow = FileData.nFileSizeLow;
1040 return TRUE;
1041}
1042
Thomas Wouters89f507f2006-12-13 04:49:30 +00001043static BOOL WINAPI
1044Py_GetFileAttributesExA(LPCSTR pszFile,
1045 GET_FILEEX_INFO_LEVELS level,
1046 LPVOID pv)
1047{
1048 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001049 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1050 /* First try to use the system's implementation, if that is
1051 available and either succeeds to gives an error other than
1052 that it isn't implemented. */
1053 check_gfax();
1054 if (gfaxa) {
1055 result = gfaxa(pszFile, level, pv);
1056 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1057 return result;
1058 }
1059 /* It's either not present, or not implemented.
1060 Emulate using FindFirstFile. */
1061 if (level != GetFileExInfoStandard) {
1062 SetLastError(ERROR_INVALID_PARAMETER);
1063 return FALSE;
1064 }
1065 /* Use GetFileAttributes to validate that the file name
1066 does not contain wildcards (which FindFirstFile would
1067 accept). */
1068 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1069 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001070 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001071}
1072
1073static BOOL WINAPI
1074Py_GetFileAttributesExW(LPCWSTR pszFile,
1075 GET_FILEEX_INFO_LEVELS level,
1076 LPVOID pv)
1077{
1078 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001079 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1080 /* First try to use the system's implementation, if that is
1081 available and either succeeds to gives an error other than
1082 that it isn't implemented. */
1083 check_gfax();
1084 if (gfaxa) {
1085 result = gfaxw(pszFile, level, pv);
1086 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1087 return result;
1088 }
1089 /* It's either not present, or not implemented.
1090 Emulate using FindFirstFile. */
1091 if (level != GetFileExInfoStandard) {
1092 SetLastError(ERROR_INVALID_PARAMETER);
1093 return FALSE;
1094 }
1095 /* Use GetFileAttributes to validate that the file name
1096 does not contain wildcards (which FindFirstFile would
1097 accept). */
1098 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1099 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001100 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001101}
1102
Martin v. Löwis14694662006-02-03 12:54:16 +00001103static int
1104win32_stat(const char* path, struct win32_stat *result)
1105{
1106 WIN32_FILE_ATTRIBUTE_DATA info;
1107 int code;
1108 char *dot;
1109 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001110 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001111 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1112 /* Protocol violation: we explicitly clear errno, instead of
1113 setting it to a POSIX error. Callers should use GetLastError. */
1114 errno = 0;
1115 return -1;
1116 } else {
1117 /* Could not get attributes on open file. Fall back to
1118 reading the directory. */
1119 if (!attributes_from_dir(path, &info)) {
1120 /* Very strange. This should not fail now */
1121 errno = 0;
1122 return -1;
1123 }
1124 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001125 }
1126 code = attribute_data_to_stat(&info, result);
1127 if (code != 0)
1128 return code;
1129 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1130 dot = strrchr(path, '.');
1131 if (dot) {
1132 if (stricmp(dot, ".bat") == 0 ||
1133 stricmp(dot, ".cmd") == 0 ||
1134 stricmp(dot, ".exe") == 0 ||
1135 stricmp(dot, ".com") == 0)
1136 result->st_mode |= 0111;
1137 }
1138 return code;
1139}
1140
1141static int
1142win32_wstat(const wchar_t* path, struct win32_stat *result)
1143{
1144 int code;
1145 const wchar_t *dot;
1146 WIN32_FILE_ATTRIBUTE_DATA info;
1147 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001148 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001149 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1150 /* Protocol violation: we explicitly clear errno, instead of
1151 setting it to a POSIX error. Callers should use GetLastError. */
1152 errno = 0;
1153 return -1;
1154 } else {
1155 /* Could not get attributes on open file. Fall back to
1156 reading the directory. */
1157 if (!attributes_from_dir_w(path, &info)) {
1158 /* Very strange. This should not fail now */
1159 errno = 0;
1160 return -1;
1161 }
1162 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001163 }
1164 code = attribute_data_to_stat(&info, result);
1165 if (code < 0)
1166 return code;
1167 /* Set IFEXEC if it is an .exe, .bat, ... */
1168 dot = wcsrchr(path, '.');
1169 if (dot) {
1170 if (_wcsicmp(dot, L".bat") == 0 ||
1171 _wcsicmp(dot, L".cmd") == 0 ||
1172 _wcsicmp(dot, L".exe") == 0 ||
1173 _wcsicmp(dot, L".com") == 0)
1174 result->st_mode |= 0111;
1175 }
1176 return code;
1177}
1178
1179static int
1180win32_fstat(int file_number, struct win32_stat *result)
1181{
1182 BY_HANDLE_FILE_INFORMATION info;
1183 HANDLE h;
1184 int type;
1185
1186 h = (HANDLE)_get_osfhandle(file_number);
1187
1188 /* Protocol violation: we explicitly clear errno, instead of
1189 setting it to a POSIX error. Callers should use GetLastError. */
1190 errno = 0;
1191
1192 if (h == INVALID_HANDLE_VALUE) {
1193 /* This is really a C library error (invalid file handle).
1194 We set the Win32 error to the closes one matching. */
1195 SetLastError(ERROR_INVALID_HANDLE);
1196 return -1;
1197 }
1198 memset(result, 0, sizeof(*result));
1199
1200 type = GetFileType(h);
1201 if (type == FILE_TYPE_UNKNOWN) {
1202 DWORD error = GetLastError();
1203 if (error != 0) {
1204 return -1;
1205 }
1206 /* else: valid but unknown file */
1207 }
1208
1209 if (type != FILE_TYPE_DISK) {
1210 if (type == FILE_TYPE_CHAR)
1211 result->st_mode = _S_IFCHR;
1212 else if (type == FILE_TYPE_PIPE)
1213 result->st_mode = _S_IFIFO;
1214 return 0;
1215 }
1216
1217 if (!GetFileInformationByHandle(h, &info)) {
1218 return -1;
1219 }
1220
1221 /* similar to stat() */
1222 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1223 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1224 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1225 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1226 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1227 /* specific to fstat() */
1228 result->st_nlink = info.nNumberOfLinks;
1229 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1230 return 0;
1231}
1232
1233#endif /* MS_WINDOWS */
1234
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001235PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001236"stat_result: Result from stat or lstat.\n\n\
1237This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001238 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001239or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1240\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001241Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1242or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001243\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001244See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001245
1246static PyStructSequence_Field stat_result_fields[] = {
1247 {"st_mode", "protection bits"},
1248 {"st_ino", "inode"},
1249 {"st_dev", "device"},
1250 {"st_nlink", "number of hard links"},
1251 {"st_uid", "user ID of owner"},
1252 {"st_gid", "group ID of owner"},
1253 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001254 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1255 {NULL, "integer time of last access"},
1256 {NULL, "integer time of last modification"},
1257 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001258 {"st_atime", "time of last access"},
1259 {"st_mtime", "time of last modification"},
1260 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001261#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001262 {"st_blksize", "blocksize for filesystem I/O"},
1263#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001264#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001265 {"st_blocks", "number of blocks allocated"},
1266#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001267#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001268 {"st_rdev", "device type (if inode device)"},
1269#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001270#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1271 {"st_flags", "user defined flags for file"},
1272#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001273#ifdef HAVE_STRUCT_STAT_ST_GEN
1274 {"st_gen", "generation number"},
1275#endif
1276#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1277 {"st_birthtime", "time of creation"},
1278#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001279 {0}
1280};
1281
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001282#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001283#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001284#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001285#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001286#endif
1287
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001288#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001289#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1290#else
1291#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1292#endif
1293
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001294#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001295#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1296#else
1297#define ST_RDEV_IDX ST_BLOCKS_IDX
1298#endif
1299
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001300#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1301#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1302#else
1303#define ST_FLAGS_IDX ST_RDEV_IDX
1304#endif
1305
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001306#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001307#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001308#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001309#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001310#endif
1311
1312#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1313#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1314#else
1315#define ST_BIRTHTIME_IDX ST_GEN_IDX
1316#endif
1317
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001318static PyStructSequence_Desc stat_result_desc = {
1319 "stat_result", /* name */
1320 stat_result__doc__, /* doc */
1321 stat_result_fields,
1322 10
1323};
1324
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001325PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001326"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1327This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001328 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001329or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001330\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001331See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001332
1333static PyStructSequence_Field statvfs_result_fields[] = {
1334 {"f_bsize", },
1335 {"f_frsize", },
1336 {"f_blocks", },
1337 {"f_bfree", },
1338 {"f_bavail", },
1339 {"f_files", },
1340 {"f_ffree", },
1341 {"f_favail", },
1342 {"f_flag", },
1343 {"f_namemax",},
1344 {0}
1345};
1346
1347static PyStructSequence_Desc statvfs_result_desc = {
1348 "statvfs_result", /* name */
1349 statvfs_result__doc__, /* doc */
1350 statvfs_result_fields,
1351 10
1352};
1353
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001354static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001355static PyTypeObject StatResultType;
1356static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001357static newfunc structseq_new;
1358
1359static PyObject *
1360statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1361{
1362 PyStructSequence *result;
1363 int i;
1364
1365 result = (PyStructSequence*)structseq_new(type, args, kwds);
1366 if (!result)
1367 return NULL;
1368 /* If we have been initialized from a tuple,
1369 st_?time might be set to None. Initialize it
1370 from the int slots. */
1371 for (i = 7; i <= 9; i++) {
1372 if (result->ob_item[i+3] == Py_None) {
1373 Py_DECREF(Py_None);
1374 Py_INCREF(result->ob_item[i]);
1375 result->ob_item[i+3] = result->ob_item[i];
1376 }
1377 }
1378 return (PyObject*)result;
1379}
1380
1381
1382
1383/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001384static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001385
1386PyDoc_STRVAR(stat_float_times__doc__,
1387"stat_float_times([newval]) -> oldval\n\n\
1388Determine whether os.[lf]stat represents time stamps as float objects.\n\
1389If newval is True, future calls to stat() return floats, if it is False,\n\
1390future calls return ints. \n\
1391If newval is omitted, return the current setting.\n");
1392
1393static PyObject*
1394stat_float_times(PyObject* self, PyObject *args)
1395{
1396 int newval = -1;
1397 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1398 return NULL;
1399 if (newval == -1)
1400 /* Return old value */
1401 return PyBool_FromLong(_stat_float_times);
1402 _stat_float_times = newval;
1403 Py_INCREF(Py_None);
1404 return Py_None;
1405}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001406
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001407static void
1408fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1409{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001410 PyObject *fval,*ival;
1411#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001412 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001413#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001414 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001415#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001416 if (!ival)
1417 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001418 if (_stat_float_times) {
1419 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1420 } else {
1421 fval = ival;
1422 Py_INCREF(fval);
1423 }
1424 PyStructSequence_SET_ITEM(v, index, ival);
1425 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001426}
1427
Tim Peters5aa91602002-01-30 05:46:57 +00001428/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001429 (used by posix_stat() and posix_fstat()) */
1430static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001431_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001432{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001433 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001434 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001435 if (v == NULL)
1436 return NULL;
1437
Christian Heimes217cfd12007-12-02 14:31:20 +00001438 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001439#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001440 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001441 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001442#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001443 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001444#endif
1445#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001446 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001447 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001448#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001449 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001450#endif
Christian Heimes217cfd12007-12-02 14:31:20 +00001451 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1452 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1453 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001454#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001455 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001456 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001457#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001458 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001459#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001460
Martin v. Löwis14694662006-02-03 12:54:16 +00001461#if defined(HAVE_STAT_TV_NSEC)
1462 ansec = st->st_atim.tv_nsec;
1463 mnsec = st->st_mtim.tv_nsec;
1464 cnsec = st->st_ctim.tv_nsec;
1465#elif defined(HAVE_STAT_TV_NSEC2)
1466 ansec = st->st_atimespec.tv_nsec;
1467 mnsec = st->st_mtimespec.tv_nsec;
1468 cnsec = st->st_ctimespec.tv_nsec;
1469#elif defined(HAVE_STAT_NSEC)
1470 ansec = st->st_atime_nsec;
1471 mnsec = st->st_mtime_nsec;
1472 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001473#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001474 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001475#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001476 fill_time(v, 7, st->st_atime, ansec);
1477 fill_time(v, 8, st->st_mtime, mnsec);
1478 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001479
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001480#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001481 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001482 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001483#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001484#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001485 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001486 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001487#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001488#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001489 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001490 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001491#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001492#ifdef HAVE_STRUCT_STAT_ST_GEN
1493 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001494 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001495#endif
1496#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1497 {
1498 PyObject *val;
1499 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001500 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001501#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001502 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001503#else
1504 bnsec = 0;
1505#endif
1506 if (_stat_float_times) {
1507 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1508 } else {
Christian Heimes217cfd12007-12-02 14:31:20 +00001509 val = PyLong_FromLong((long)bsec);
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001510 }
1511 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1512 val);
1513 }
1514#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001515#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1516 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001517 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001518#endif
Fred Drake699f3522000-06-29 21:12:41 +00001519
1520 if (PyErr_Occurred()) {
1521 Py_DECREF(v);
1522 return NULL;
1523 }
1524
1525 return v;
1526}
1527
Martin v. Löwisd8948722004-06-02 09:57:56 +00001528#ifdef MS_WINDOWS
1529
1530/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1531 where / can be used in place of \ and the trailing slash is optional.
1532 Both SERVER and SHARE must have at least one character.
1533*/
1534
1535#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1536#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001537#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001538#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001539#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001540
Tim Peters4ad82172004-08-30 17:02:04 +00001541static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001542IsUNCRootA(char *path, int pathlen)
1543{
1544 #define ISSLASH ISSLASHA
1545
1546 int i, share;
1547
1548 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1549 /* minimum UNCRoot is \\x\y */
1550 return FALSE;
1551 for (i = 2; i < pathlen ; i++)
1552 if (ISSLASH(path[i])) break;
1553 if (i == 2 || i == pathlen)
1554 /* do not allow \\\SHARE or \\SERVER */
1555 return FALSE;
1556 share = i+1;
1557 for (i = share; i < pathlen; i++)
1558 if (ISSLASH(path[i])) break;
1559 return (i != share && (i == pathlen || i == pathlen-1));
1560
1561 #undef ISSLASH
1562}
1563
1564#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001565static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001566IsUNCRootW(Py_UNICODE *path, int pathlen)
1567{
1568 #define ISSLASH ISSLASHW
1569
1570 int i, share;
1571
1572 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1573 /* minimum UNCRoot is \\x\y */
1574 return FALSE;
1575 for (i = 2; i < pathlen ; i++)
1576 if (ISSLASH(path[i])) break;
1577 if (i == 2 || i == pathlen)
1578 /* do not allow \\\SHARE or \\SERVER */
1579 return FALSE;
1580 share = i+1;
1581 for (i = share; i < pathlen; i++)
1582 if (ISSLASH(path[i])) break;
1583 return (i != share && (i == pathlen || i == pathlen-1));
1584
1585 #undef ISSLASH
1586}
1587#endif /* Py_WIN_WIDE_FILENAMES */
1588#endif /* MS_WINDOWS */
1589
Barry Warsaw53699e91996-12-10 23:23:01 +00001590static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001591posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001592 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001593#ifdef __VMS
1594 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1595#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001596 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001597#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001598 char *wformat,
1599 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001600{
Fred Drake699f3522000-06-29 21:12:41 +00001601 STRUCT_STAT st;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001602 PyObject *opath;
1603 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001604 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001605 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001606
1607#ifdef Py_WIN_WIDE_FILENAMES
1608 /* If on wide-character-capable OS see if argument
1609 is Unicode and if so use wide API. */
1610 if (unicode_file_names()) {
1611 PyUnicodeObject *po;
1612 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001613 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1614
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001615 Py_BEGIN_ALLOW_THREADS
1616 /* PyUnicode_AS_UNICODE result OK without
1617 thread lock as it is a simple dereference. */
1618 res = wstatfunc(wpath, &st);
1619 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001620
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001621 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001622 return win32_error_unicode("stat", wpath);
1623 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001624 }
1625 /* Drop the argument parsing error as narrow strings
1626 are also valid. */
1627 PyErr_Clear();
1628 }
1629#endif
1630
Tim Peters5aa91602002-01-30 05:46:57 +00001631 if (!PyArg_ParseTuple(args, format,
Martin v. Löwis011e8422009-05-05 04:43:17 +00001632 PyUnicode_FSConverter, &opath))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001633 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001634 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00001635 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001636 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001637 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001638
1639 if (res != 0) {
1640#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00001641 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001642#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00001643 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001644#endif
1645 }
1646 else
1647 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001648
Martin v. Löwis011e8422009-05-05 04:43:17 +00001649 release_bytes(opath);
Martin v. Löwis14694662006-02-03 12:54:16 +00001650 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001651}
1652
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001653/* POSIX methods */
1654
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001655PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001656"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001657Use the real uid/gid to test for access to a path. Note that most\n\
1658operations will use the effective uid/gid, therefore this routine can\n\
1659be used in a suid/sgid environment to test if the invoking user has the\n\
1660specified access to the path. The mode argument can be F_OK to test\n\
1661existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001662
1663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001664posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001665{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001666 PyObject *opath;
Guido van Rossum015f22a1999-01-06 22:52:38 +00001667 char *path;
1668 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001669
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001670#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001671 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001672 if (unicode_file_names()) {
1673 PyUnicodeObject *po;
1674 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1675 Py_BEGIN_ALLOW_THREADS
1676 /* PyUnicode_AS_UNICODE OK without thread lock as
1677 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001678 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001679 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001680 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001681 }
1682 /* Drop the argument parsing error as narrow strings
1683 are also valid. */
1684 PyErr_Clear();
1685 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00001686 if (!PyArg_ParseTuple(args, "O&i:access",
1687 PyUnicode_FSConverter, &opath, &mode))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001688 return 0;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001689 path = bytes2str(opath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001690 Py_BEGIN_ALLOW_THREADS
1691 attr = GetFileAttributesA(path);
1692 Py_END_ALLOW_THREADS
Martin v. Löwis011e8422009-05-05 04:43:17 +00001693 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001694finish:
1695 if (attr == 0xFFFFFFFF)
1696 /* File does not exist, or cannot read attributes */
1697 return PyBool_FromLong(0);
1698 /* Access is possible if either write access wasn't requested, or
Guido van Rossumb00324f2007-12-04 01:13:14 +00001699 the file isn't read-only, or if it's a directory, as there are
1700 no read-only directories on Windows. */
1701 return PyBool_FromLong(!(mode & 2)
1702 || !(attr & FILE_ATTRIBUTE_READONLY)
1703 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001704#else
1705 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001706 if (!PyArg_ParseTuple(args, "O&i:access",
1707 PyUnicode_FSConverter, &opath, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001708 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001709 path = bytes2str(opath, 1);
Guido van Rossum015f22a1999-01-06 22:52:38 +00001710 Py_BEGIN_ALLOW_THREADS
1711 res = access(path, mode);
1712 Py_END_ALLOW_THREADS
Martin v. Löwis011e8422009-05-05 04:43:17 +00001713 release_bytes(opath);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001714 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001715#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001716}
1717
Guido van Rossumd371ff11999-01-25 16:12:23 +00001718#ifndef F_OK
1719#define F_OK 0
1720#endif
1721#ifndef R_OK
1722#define R_OK 4
1723#endif
1724#ifndef W_OK
1725#define W_OK 2
1726#endif
1727#ifndef X_OK
1728#define X_OK 1
1729#endif
1730
1731#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001732PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001733"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001734Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001735
1736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001737posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001738{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001739 int id;
1740 char *ret;
1741
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001742 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001743 return NULL;
1744
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001745#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001746 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001747 if (id == 0) {
1748 ret = ttyname();
1749 }
1750 else {
1751 ret = NULL;
1752 }
1753#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001754 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001755#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001756 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001757 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001758 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001759}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001760#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001761
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001762#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001763PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001764"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001765Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001766
1767static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001768posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001769{
1770 char *ret;
1771 char buffer[L_ctermid];
1772
Greg Wardb48bc172000-03-01 21:51:56 +00001773#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001774 ret = ctermid_r(buffer);
1775#else
1776 ret = ctermid(buffer);
1777#endif
1778 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001779 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001780 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001781}
1782#endif
1783
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001784PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001785"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001786Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001787
Barry Warsaw53699e91996-12-10 23:23:01 +00001788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001789posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001790{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001791#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00001792 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001793#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001794 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001795#elif defined(__VMS)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001796 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001797#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00001798 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001799#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001800}
1801
Fred Drake4d1e64b2002-04-15 19:40:07 +00001802#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001803PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001804"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001805Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001806opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001807
1808static PyObject *
1809posix_fchdir(PyObject *self, PyObject *fdobj)
1810{
1811 return posix_fildes(fdobj, fchdir);
1812}
1813#endif /* HAVE_FCHDIR */
1814
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001815
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001816PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001817"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001818Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001819
Barry Warsaw53699e91996-12-10 23:23:01 +00001820static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001821posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001822{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001823 PyObject *opath = NULL;
Mark Hammondef8b6542001-05-13 08:04:26 +00001824 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001825 int i;
1826 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001827#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001828 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001829 if (unicode_file_names()) {
1830 PyUnicodeObject *po;
1831 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1832 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001833 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1834 if (attr != 0xFFFFFFFF) {
1835 if (i & _S_IWRITE)
1836 attr &= ~FILE_ATTRIBUTE_READONLY;
1837 else
1838 attr |= FILE_ATTRIBUTE_READONLY;
1839 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1840 }
1841 else
1842 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001843 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001844 if (!res)
1845 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001846 PyUnicode_AS_UNICODE(po));
1847 Py_INCREF(Py_None);
1848 return Py_None;
1849 }
1850 /* Drop the argument parsing error as narrow strings
1851 are also valid. */
1852 PyErr_Clear();
1853 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00001854 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1855 &opath, &i))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001856 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001857 path = bytes2str(opath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001858 Py_BEGIN_ALLOW_THREADS
1859 attr = GetFileAttributesA(path);
1860 if (attr != 0xFFFFFFFF) {
1861 if (i & _S_IWRITE)
1862 attr &= ~FILE_ATTRIBUTE_READONLY;
1863 else
1864 attr |= FILE_ATTRIBUTE_READONLY;
1865 res = SetFileAttributesA(path, attr);
1866 }
1867 else
1868 res = 0;
1869 Py_END_ALLOW_THREADS
1870 if (!res) {
1871 win32_error("chmod", path);
Martin v. Löwis011e8422009-05-05 04:43:17 +00001872 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001873 return NULL;
1874 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00001875 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001876 Py_INCREF(Py_None);
1877 return Py_None;
1878#else /* Py_WIN_WIDE_FILENAMES */
Martin v. Löwis011e8422009-05-05 04:43:17 +00001879 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1880 &opath, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001881 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001882 path = bytes2str(opath, 1);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001883 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001884 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001885 Py_END_ALLOW_THREADS
1886 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001887 return posix_error_with_allocated_filename(opath);
1888 release_bytes(opath);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001889 Py_INCREF(Py_None);
1890 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001891#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001892}
1893
Christian Heimes4e30a842007-11-30 22:12:06 +00001894#ifdef HAVE_FCHMOD
1895PyDoc_STRVAR(posix_fchmod__doc__,
1896"fchmod(fd, mode)\n\n\
1897Change the access permissions of the file given by file\n\
1898descriptor fd.");
1899
1900static PyObject *
1901posix_fchmod(PyObject *self, PyObject *args)
1902{
1903 int fd, mode, res;
1904 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1905 return NULL;
1906 Py_BEGIN_ALLOW_THREADS
1907 res = fchmod(fd, mode);
1908 Py_END_ALLOW_THREADS
1909 if (res < 0)
1910 return posix_error();
1911 Py_RETURN_NONE;
1912}
1913#endif /* HAVE_FCHMOD */
1914
1915#ifdef HAVE_LCHMOD
1916PyDoc_STRVAR(posix_lchmod__doc__,
1917"lchmod(path, mode)\n\n\
1918Change the access permissions of a file. If path is a symlink, this\n\
1919affects the link itself rather than the target.");
1920
1921static PyObject *
1922posix_lchmod(PyObject *self, PyObject *args)
1923{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001924 PyObject *opath;
1925 char *path;
Christian Heimes4e30a842007-11-30 22:12:06 +00001926 int i;
1927 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001928 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1929 &opath, &i))
Christian Heimes4e30a842007-11-30 22:12:06 +00001930 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001931 path = bytes2str(opath, 1)
Christian Heimes4e30a842007-11-30 22:12:06 +00001932 Py_BEGIN_ALLOW_THREADS
1933 res = lchmod(path, i);
1934 Py_END_ALLOW_THREADS
1935 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001936 return posix_error_with_allocated_filename(opath);
1937 release_bytes(opath);
Christian Heimes4e30a842007-11-30 22:12:06 +00001938 Py_RETURN_NONE;
1939}
1940#endif /* HAVE_LCHMOD */
1941
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001942
Thomas Wouterscf297e42007-02-23 15:07:44 +00001943#ifdef HAVE_CHFLAGS
1944PyDoc_STRVAR(posix_chflags__doc__,
1945"chflags(path, flags)\n\n\
1946Set file flags.");
1947
1948static PyObject *
1949posix_chflags(PyObject *self, PyObject *args)
1950{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001951 PyObject *opath;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001952 char *path;
1953 unsigned long flags;
1954 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001955 if (!PyArg_ParseTuple(args, "O&k:chflags",
1956 PyUnicode_FSConverter, &opath, &flags))
Thomas Wouterscf297e42007-02-23 15:07:44 +00001957 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001958 path = bytes2str(opath, 1);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001959 Py_BEGIN_ALLOW_THREADS
1960 res = chflags(path, flags);
1961 Py_END_ALLOW_THREADS
1962 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001963 return posix_error_with_allocated_filename(opath);
1964 release_bytes(opath);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001965 Py_INCREF(Py_None);
1966 return Py_None;
1967}
1968#endif /* HAVE_CHFLAGS */
1969
1970#ifdef HAVE_LCHFLAGS
1971PyDoc_STRVAR(posix_lchflags__doc__,
1972"lchflags(path, flags)\n\n\
1973Set file flags.\n\
1974This function will not follow symbolic links.");
1975
1976static PyObject *
1977posix_lchflags(PyObject *self, PyObject *args)
1978{
Martin v. Löwis011e8422009-05-05 04:43:17 +00001979 PyObject *opath;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001980 char *path;
1981 unsigned long flags;
1982 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001983 if (!PyArg_ParseTuple(args, "O&k:lchflags",
1984 PyUnicode_FSConverter, &path, &flags))
Thomas Wouterscf297e42007-02-23 15:07:44 +00001985 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00001986 path = bytes2str(opath, 1);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001987 Py_BEGIN_ALLOW_THREADS
1988 res = lchflags(path, flags);
1989 Py_END_ALLOW_THREADS
1990 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00001991 return posix_error_with_allocated_filename(opath);
1992 release_bytes(opath);
Thomas Wouterscf297e42007-02-23 15:07:44 +00001993 Py_INCREF(Py_None);
1994 return Py_None;
1995}
1996#endif /* HAVE_LCHFLAGS */
1997
Martin v. Löwis244edc82001-10-04 22:44:26 +00001998#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001999PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002000"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002001Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002002
2003static PyObject *
2004posix_chroot(PyObject *self, PyObject *args)
2005{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002006 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002007}
2008#endif
2009
Guido van Rossum21142a01999-01-08 21:05:37 +00002010#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002011PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002012"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002013force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002014
2015static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002016posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002017{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002018 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002019}
2020#endif /* HAVE_FSYNC */
2021
2022#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002023
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002024#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002025extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2026#endif
2027
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002029"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002030force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002031 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002032
2033static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002034posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002035{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002036 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002037}
2038#endif /* HAVE_FDATASYNC */
2039
2040
Fredrik Lundh10723342000-07-10 16:38:09 +00002041#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002042PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002043"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002044Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002045
Barry Warsaw53699e91996-12-10 23:23:01 +00002046static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002047posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002048{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002049 PyObject *opath;
2050 char *path;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00002051 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00002052 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002053 if (!PyArg_ParseTuple(args, "O&ll:chown",
2054 PyUnicode_FSConverter, &opath,
Mark Hammondef8b6542001-05-13 08:04:26 +00002055 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00002056 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002057 path = bytes2str(opath, 1);
Fredrik Lundh44328e62000-07-10 15:59:30 +00002058 Py_BEGIN_ALLOW_THREADS
2059 res = chown(path, (uid_t) uid, (gid_t) gid);
2060 Py_END_ALLOW_THREADS
2061 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00002062 return posix_error_with_allocated_filename(opath);
2063 release_bytes(opath);
Fredrik Lundh44328e62000-07-10 15:59:30 +00002064 Py_INCREF(Py_None);
2065 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002066}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002067#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002068
Christian Heimes4e30a842007-11-30 22:12:06 +00002069#ifdef HAVE_FCHOWN
2070PyDoc_STRVAR(posix_fchown__doc__,
2071"fchown(fd, uid, gid)\n\n\
2072Change the owner and group id of the file given by file descriptor\n\
2073fd to the numeric uid and gid.");
2074
2075static PyObject *
2076posix_fchown(PyObject *self, PyObject *args)
2077{
2078 int fd, uid, gid;
2079 int res;
2080 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
2081 return NULL;
2082 Py_BEGIN_ALLOW_THREADS
2083 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2084 Py_END_ALLOW_THREADS
2085 if (res < 0)
2086 return posix_error();
2087 Py_RETURN_NONE;
2088}
2089#endif /* HAVE_FCHOWN */
2090
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002091#ifdef HAVE_LCHOWN
2092PyDoc_STRVAR(posix_lchown__doc__,
2093"lchown(path, uid, gid)\n\n\
2094Change the owner and group id of path to the numeric uid and gid.\n\
2095This function will not follow symbolic links.");
2096
2097static PyObject *
2098posix_lchown(PyObject *self, PyObject *args)
2099{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002100 PyObject *opath;
2101 char *path;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002102 int uid, gid;
2103 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002104 if (!PyArg_ParseTuple(args, "O&ii:lchown",
2105 PyUnicode_FSConverter, &opath,
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002106 &uid, &gid))
2107 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002108 path = bytes2str(opath, 1);
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002109 Py_BEGIN_ALLOW_THREADS
2110 res = lchown(path, (uid_t) uid, (gid_t) gid);
2111 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00002112 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00002113 return posix_error_with_allocated_filename(opath);
2114 release_bytes(opath);
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002115 Py_INCREF(Py_None);
2116 return Py_None;
2117}
2118#endif /* HAVE_LCHOWN */
2119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002120
Guido van Rossum36bc6801995-06-14 22:54:23 +00002121#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002122static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002123posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002124{
2125 char buf[1026];
2126 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002127
2128#ifdef Py_WIN_WIDE_FILENAMES
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002129 if (!use_bytes && unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002130 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00002131 wchar_t *wbuf2 = wbuf;
2132 PyObject *resobj;
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002133 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002134 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002135 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2136 /* If the buffer is large enough, len does not include the
2137 terminating \0. If the buffer is too small, len includes
2138 the space needed for the terminator. */
2139 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2140 wbuf2 = malloc(len * sizeof(wchar_t));
2141 if (wbuf2)
2142 len = GetCurrentDirectoryW(len, wbuf2);
2143 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002144 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002145 if (!wbuf2) {
2146 PyErr_NoMemory();
2147 return NULL;
2148 }
2149 if (!len) {
2150 if (wbuf2 != wbuf) free(wbuf2);
2151 return win32_error("getcwdu", NULL);
2152 }
2153 resobj = PyUnicode_FromWideChar(wbuf2, len);
2154 if (wbuf2 != wbuf) free(wbuf2);
2155 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002156 }
2157#endif
2158
2159 Py_BEGIN_ALLOW_THREADS
2160#if defined(PYOS_OS2) && defined(PYCC_GCC)
2161 res = _getcwd2(buf, sizeof buf);
2162#else
2163 res = getcwd(buf, sizeof buf);
2164#endif
2165 Py_END_ALLOW_THREADS
2166 if (res == NULL)
2167 return posix_error();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002168 if (use_bytes)
2169 return PyBytes_FromStringAndSize(buf, strlen(buf));
Martin v. Löwis011e8422009-05-05 04:43:17 +00002170 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"utf8b");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002171}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002172
2173PyDoc_STRVAR(posix_getcwd__doc__,
2174"getcwd() -> path\n\n\
2175Return a unicode string representing the current working directory.");
2176
2177static PyObject *
2178posix_getcwd_unicode(PyObject *self)
2179{
2180 return posix_getcwd(0);
2181}
2182
2183PyDoc_STRVAR(posix_getcwdb__doc__,
2184"getcwdb() -> path\n\n\
2185Return a bytes string representing the current working directory.");
2186
2187static PyObject *
2188posix_getcwd_bytes(PyObject *self)
2189{
2190 return posix_getcwd(1);
2191}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002192#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002194
Guido van Rossumb6775db1994-08-01 11:34:53 +00002195#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002196PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002197"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002198Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002199
Barry Warsaw53699e91996-12-10 23:23:01 +00002200static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002201posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002202{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002203 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002204}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002205#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002208PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002209"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002210Return a list containing the names of the entries in the directory.\n\
2211\n\
2212 path: path of directory to list\n\
2213\n\
2214The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002215entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002216
Barry Warsaw53699e91996-12-10 23:23:01 +00002217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002218posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002219{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002220 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002221 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002222#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002223
Barry Warsaw53699e91996-12-10 23:23:01 +00002224 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002225 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002226 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002227 WIN32_FIND_DATA FileData;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002228 PyObject *opath;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002229 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002230 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002231 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002232
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002233#ifdef Py_WIN_WIDE_FILENAMES
2234 /* If on wide-character-capable OS see if argument
2235 is Unicode and if so use wide API. */
2236 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002237 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002238 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2239 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002240 Py_UNICODE *wnamebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002241 /* Overallocate for \\*.*\0 */
2242 len = PyUnicode_GET_SIZE(po);
2243 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2244 if (!wnamebuf) {
2245 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002246 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002247 }
2248 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
Hirokazu Yamamotobbb9be72009-05-04 05:56:46 +00002249 if (len > 0) {
2250 Py_UNICODE wch = wnamebuf[len-1];
2251 if (wch != L'/' && wch != L'\\' && wch != L':')
2252 wnamebuf[len++] = L'\\';
2253 wcscpy(wnamebuf + len, L"*.*");
2254 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002255 if ((d = PyList_New(0)) == NULL) {
2256 free(wnamebuf);
2257 return NULL;
2258 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002259 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2260 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002261 int error = GetLastError();
2262 if (error == ERROR_FILE_NOT_FOUND) {
2263 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002264 return d;
2265 }
2266 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002267 win32_error_unicode("FindFirstFileW", wnamebuf);
2268 free(wnamebuf);
2269 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002270 }
2271 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002272 /* Skip over . and .. */
2273 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2274 wcscmp(wFileData.cFileName, L"..") != 0) {
2275 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2276 if (v == NULL) {
2277 Py_DECREF(d);
2278 d = NULL;
2279 break;
2280 }
2281 if (PyList_Append(d, v) != 0) {
2282 Py_DECREF(v);
2283 Py_DECREF(d);
2284 d = NULL;
2285 break;
2286 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002287 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002288 }
Georg Brandl622927b2006-03-07 12:48:03 +00002289 Py_BEGIN_ALLOW_THREADS
2290 result = FindNextFileW(hFindFile, &wFileData);
2291 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002292 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2293 it got to the end of the directory. */
2294 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2295 Py_DECREF(d);
2296 win32_error_unicode("FindNextFileW", wnamebuf);
2297 FindClose(hFindFile);
2298 free(wnamebuf);
2299 return NULL;
2300 }
Georg Brandl622927b2006-03-07 12:48:03 +00002301 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002302
2303 if (FindClose(hFindFile) == FALSE) {
2304 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002305 win32_error_unicode("FindClose", wnamebuf);
2306 free(wnamebuf);
2307 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002308 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002309 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002310 return d;
2311 }
2312 /* Drop the argument parsing error as narrow strings
2313 are also valid. */
2314 PyErr_Clear();
2315 }
2316#endif
2317
Martin v. Löwis011e8422009-05-05 04:43:17 +00002318 if (!PyArg_ParseTuple(args, "O&:listdir",
2319 PyUnicode_FSConverter, &opath))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002320 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002321 if (PyObject_Size(opath)+1 > MAX_PATH) {
2322 PyErr_SetString(PyExc_ValueError, "path too long");
2323 Py_DECREF(opath);
2324 return NULL;
2325 }
2326 strcpy(namebuf, bytes2str(opath, 0));
2327 len = PyObject_Size(opath);
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002328 if (len > 0) {
2329 char ch = namebuf[len-1];
2330 if (ch != SEP && ch != ALTSEP && ch != ':')
2331 namebuf[len++] = '/';
Hirokazu Yamamotobbb9be72009-05-04 05:56:46 +00002332 strcpy(namebuf + len, "*.*");
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002333 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002334
Barry Warsaw53699e91996-12-10 23:23:01 +00002335 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002336 return NULL;
2337
2338 hFindFile = FindFirstFile(namebuf, &FileData);
2339 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002340 int error = GetLastError();
2341 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002342 return d;
2343 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002344 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002345 }
2346 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002347 /* Skip over . and .. */
2348 if (strcmp(FileData.cFileName, ".") != 0 &&
2349 strcmp(FileData.cFileName, "..") != 0) {
Christian Heimes72b710a2008-05-26 13:28:38 +00002350 v = PyBytes_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002351 if (v == NULL) {
2352 Py_DECREF(d);
2353 d = NULL;
2354 break;
2355 }
2356 if (PyList_Append(d, v) != 0) {
2357 Py_DECREF(v);
2358 Py_DECREF(d);
2359 d = NULL;
2360 break;
2361 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002362 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002363 }
Georg Brandl622927b2006-03-07 12:48:03 +00002364 Py_BEGIN_ALLOW_THREADS
2365 result = FindNextFile(hFindFile, &FileData);
2366 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002367 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2368 it got to the end of the directory. */
2369 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2370 Py_DECREF(d);
2371 win32_error("FindNextFile", namebuf);
2372 FindClose(hFindFile);
2373 return NULL;
2374 }
Georg Brandl622927b2006-03-07 12:48:03 +00002375 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002376
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002377 if (FindClose(hFindFile) == FALSE) {
2378 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002379 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002380 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002381
2382 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002383
Tim Peters0bb44a42000-09-15 07:44:49 +00002384#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002385
2386#ifndef MAX_PATH
2387#define MAX_PATH CCHMAXPATH
2388#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002389 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002390 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002391 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002392 PyObject *d, *v;
2393 char namebuf[MAX_PATH+5];
2394 HDIR hdir = 1;
2395 ULONG srchcnt = 1;
2396 FILEFINDBUF3 ep;
2397 APIRET rc;
2398
Martin v. Löwis011e8422009-05-05 04:43:17 +00002399 if (!PyArg_ParseTuple(args, "O&:listdir",
2400 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002401 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002402 name = bytes2str(oname);
2403 len = PyObject_Size(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002404 if (len >= MAX_PATH) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002405 release_bytes(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002406 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002407 return NULL;
2408 }
2409 strcpy(namebuf, name);
2410 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002411 if (*pt == ALTSEP)
2412 *pt = SEP;
2413 if (namebuf[len-1] != SEP)
2414 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002415 strcpy(namebuf + len, "*.*");
2416
Neal Norwitz6c913782007-10-14 03:23:09 +00002417 if ((d = PyList_New(0)) == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002418 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002419 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002420 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002421
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002422 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2423 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002424 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002425 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2426 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2427 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002428
2429 if (rc != NO_ERROR) {
2430 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002431 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002432 }
2433
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002434 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002435 do {
2436 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002437 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002438 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002439
2440 strcpy(namebuf, ep.achName);
2441
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002442 /* Leave Case of Name Alone -- In Native Form */
2443 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002444
Christian Heimes72b710a2008-05-26 13:28:38 +00002445 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002446 if (v == NULL) {
2447 Py_DECREF(d);
2448 d = NULL;
2449 break;
2450 }
2451 if (PyList_Append(d, v) != 0) {
2452 Py_DECREF(v);
2453 Py_DECREF(d);
2454 d = NULL;
2455 break;
2456 }
2457 Py_DECREF(v);
2458 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2459 }
2460
Martin v. Löwis011e8422009-05-05 04:43:17 +00002461 release_bytes(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002462 return d;
2463#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002464 PyObject *oname;
2465 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00002466 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002467 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002468 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002469 int arg_is_unicode = 1;
2470
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002471 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002472 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2473 arg_is_unicode = 0;
2474 PyErr_Clear();
2475 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002476 if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002477 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002478 name = bytes2str(oname, 1);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002479 if ((dirp = opendir(name)) == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002480 return posix_error_with_allocated_filename(oname);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002481 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002482 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002483 closedir(dirp);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002484 release_bytes(oname);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002485 return NULL;
2486 }
Georg Brandl622927b2006-03-07 12:48:03 +00002487 for (;;) {
Georg Brandl3dbca812008-07-23 16:10:53 +00002488 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002489 Py_BEGIN_ALLOW_THREADS
2490 ep = readdir(dirp);
2491 Py_END_ALLOW_THREADS
Georg Brandl3dbca812008-07-23 16:10:53 +00002492 if (ep == NULL) {
2493 if (errno == 0) {
2494 break;
2495 } else {
2496 closedir(dirp);
2497 Py_DECREF(d);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002498 return posix_error_with_allocated_filename(oname);
Georg Brandl3dbca812008-07-23 16:10:53 +00002499 }
2500 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002501 if (ep->d_name[0] == '.' &&
2502 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002503 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002504 continue;
Christian Heimes72b710a2008-05-26 13:28:38 +00002505 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002506 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002507 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002508 d = NULL;
2509 break;
2510 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002511 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002512 PyObject *w;
2513
2514 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002515 Py_FileSystemDefaultEncoding,
Martin v. Löwis011e8422009-05-05 04:43:17 +00002516 "utf8b");
2517 Py_DECREF(v);
2518 if (w != NULL)
Just van Rossum6a421832003-03-04 19:30:44 +00002519 v = w;
Just van Rossum6a421832003-03-04 19:30:44 +00002520 else {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002521 /* Encoding failed to decode ASCII bytes.
2522 Raise exception. */
2523 Py_DECREF(d);
2524 d = NULL;
2525 break;
Just van Rossum46c97842003-02-25 21:42:15 +00002526 }
Just van Rossum46c97842003-02-25 21:42:15 +00002527 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002528 if (PyList_Append(d, v) != 0) {
2529 Py_DECREF(v);
2530 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002531 d = NULL;
2532 break;
2533 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002534 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002535 }
2536 closedir(dirp);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002537 release_bytes(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002538
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002539 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002540
Tim Peters0bb44a42000-09-15 07:44:49 +00002541#endif /* which OS */
2542} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002543
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002544#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002545/* A helper function for abspath on win32 */
2546static PyObject *
2547posix__getfullpathname(PyObject *self, PyObject *args)
2548{
Martin v. Löwis011e8422009-05-05 04:43:17 +00002549 PyObject *opath;
2550 char *path;
Mark Hammondef8b6542001-05-13 08:04:26 +00002551 char outbuf[MAX_PATH*2];
2552 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002553#ifdef Py_WIN_WIDE_FILENAMES
2554 if (unicode_file_names()) {
2555 PyUnicodeObject *po;
2556 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
Benjamin Petersonf608c612008-11-16 18:33:53 +00002557 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2558 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002559 Py_UNICODE *wtemp;
Benjamin Petersonf608c612008-11-16 18:33:53 +00002560 DWORD result;
2561 PyObject *v;
2562 result = GetFullPathNameW(wpath,
2563 sizeof(woutbuf)/sizeof(woutbuf[0]),
2564 woutbuf, &wtemp);
2565 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2566 woutbufp = malloc(result * sizeof(Py_UNICODE));
2567 if (!woutbufp)
2568 return PyErr_NoMemory();
2569 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2570 }
2571 if (result)
2572 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2573 else
2574 v = win32_error_unicode("GetFullPathNameW", wpath);
2575 if (woutbufp != woutbuf)
2576 free(woutbufp);
2577 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002578 }
2579 /* Drop the argument parsing error as narrow strings
2580 are also valid. */
2581 PyErr_Clear();
2582 }
2583#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002584 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2585 PyUnicode_FSConverter, &opath))
Mark Hammondef8b6542001-05-13 08:04:26 +00002586 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002587 path = bytes2str(opath, 1);
2588 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2589 outbuf, &temp)) {
2590 win32_error("GetFullPathName", path);
2591 release_bytes(opath);
2592 return NULL;
2593 }
2594 release_bytes(opath);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002595 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2596 return PyUnicode_Decode(outbuf, strlen(outbuf),
2597 Py_FileSystemDefaultEncoding, NULL);
2598 }
Christian Heimes72b710a2008-05-26 13:28:38 +00002599 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002600} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002601#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002602
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002603PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002604"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002605Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002606
Barry Warsaw53699e91996-12-10 23:23:01 +00002607static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002608posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002609{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002610 int res;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002611 PyObject *opath;
2612 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002613 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002614
2615#ifdef Py_WIN_WIDE_FILENAMES
2616 if (unicode_file_names()) {
2617 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002618 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002619 Py_BEGIN_ALLOW_THREADS
2620 /* PyUnicode_AS_UNICODE OK without thread lock as
2621 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002622 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002623 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002624 if (!res)
2625 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002626 Py_INCREF(Py_None);
2627 return Py_None;
2628 }
2629 /* Drop the argument parsing error as narrow strings
2630 are also valid. */
2631 PyErr_Clear();
2632 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002633 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2634 PyUnicode_FSConverter, &opath, &mode))
Thomas Wouters477c8d52006-05-27 19:21:47 +00002635 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002636 path = bytes2str(opath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002637 Py_BEGIN_ALLOW_THREADS
2638 /* PyUnicode_AS_UNICODE OK without thread lock as
2639 it is a simple dereference. */
2640 res = CreateDirectoryA(path, NULL);
2641 Py_END_ALLOW_THREADS
2642 if (!res) {
2643 win32_error("mkdir", path);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002644 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002645 return NULL;
2646 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002647 release_bytes(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002648 Py_INCREF(Py_None);
2649 return Py_None;
2650#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002651
Martin v. Löwis011e8422009-05-05 04:43:17 +00002652 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2653 PyUnicode_FSConverter, &opath, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002654 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002655 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00002656 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002657#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002658 res = mkdir(path);
2659#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002660 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002661#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002662 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002663 if (res < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00002664 return posix_error_with_allocated_filename(opath);
2665 release_bytes(opath);
Barry Warsaw53699e91996-12-10 23:23:01 +00002666 Py_INCREF(Py_None);
2667 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002668#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002669}
2670
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002671
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002672/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2673#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002674#include <sys/resource.h>
2675#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002676
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002677
2678#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002679PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002680"nice(inc) -> new_priority\n\n\
2681Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002682
Barry Warsaw53699e91996-12-10 23:23:01 +00002683static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002684posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002685{
2686 int increment, value;
2687
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002688 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002689 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002690
2691 /* There are two flavours of 'nice': one that returns the new
2692 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002693 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2694 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002695
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002696 If we are of the nice family that returns the new priority, we
2697 need to clear errno before the call, and check if errno is filled
2698 before calling posix_error() on a returnvalue of -1, because the
2699 -1 may be the actual new priority! */
2700
2701 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002702 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002703#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002704 if (value == 0)
2705 value = getpriority(PRIO_PROCESS, 0);
2706#endif
2707 if (value == -1 && errno != 0)
2708 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002709 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002710 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002711}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002712#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002713
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002714PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002715"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002716Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002717
Barry Warsaw53699e91996-12-10 23:23:01 +00002718static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002719posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002720{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002721#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002722 PyObject *o1, *o2;
2723 char *p1, *p2;
2724 BOOL result;
2725 if (unicode_file_names()) {
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002726 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2727 goto error;
2728 if (!convert_to_unicode(&o1))
2729 goto error;
2730 if (!convert_to_unicode(&o2)) {
2731 Py_DECREF(o1);
2732 goto error;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002733 }
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002734 Py_BEGIN_ALLOW_THREADS
2735 result = MoveFileW(PyUnicode_AsUnicode(o1),
2736 PyUnicode_AsUnicode(o2));
2737 Py_END_ALLOW_THREADS
2738 Py_DECREF(o1);
2739 Py_DECREF(o2);
2740 if (!result)
2741 return win32_error("rename", NULL);
2742 Py_INCREF(Py_None);
2743 return Py_None;
2744error:
2745 PyErr_Clear();
Thomas Wouters477c8d52006-05-27 19:21:47 +00002746 }
2747 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2748 return NULL;
2749 Py_BEGIN_ALLOW_THREADS
2750 result = MoveFileA(p1, p2);
2751 Py_END_ALLOW_THREADS
2752 if (!result)
2753 return win32_error("rename", NULL);
2754 Py_INCREF(Py_None);
2755 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002756#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002757 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002758#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002759}
2760
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002761
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002762PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002763"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002764Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002765
Barry Warsaw53699e91996-12-10 23:23:01 +00002766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002767posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002768{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002769#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002770 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002771#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002772 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002773#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002774}
2775
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002776
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002777PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002778"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002779Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002780
Barry Warsaw53699e91996-12-10 23:23:01 +00002781static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002782posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002783{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002784#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00002785 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002786#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002787 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002788#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002789}
2790
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002791
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002792#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002793PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002794"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002795Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002796
Barry Warsaw53699e91996-12-10 23:23:01 +00002797static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002798posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002799{
Guido van Rossumff4949e1992-08-05 19:58:53 +00002800 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002801#ifdef MS_WINDOWS
2802 wchar_t *command;
2803 if (!PyArg_ParseTuple(args, "u:system", &command))
2804 return NULL;
2805#else
2806 char *command;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002807 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002808 return NULL;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002809#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002810 Py_BEGIN_ALLOW_THREADS
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002811#ifdef MS_WINDOWS
2812 sts = _wsystem(command);
2813#else
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002814 sts = system(command);
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002815#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002816 Py_END_ALLOW_THREADS
Christian Heimes217cfd12007-12-02 14:31:20 +00002817 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002818}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002819#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002820
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002821
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002822PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002823"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002824Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002825
Barry Warsaw53699e91996-12-10 23:23:01 +00002826static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002827posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002828{
2829 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002830 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002831 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002832 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002833 if (i < 0)
2834 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002835 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002836}
2837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002840"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002841Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002842
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002843PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002844"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002845Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002846
Barry Warsaw53699e91996-12-10 23:23:01 +00002847static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002848posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002849{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002850#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002851 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002852#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00002853 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002854#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002855}
2856
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002857
Guido van Rossumb6775db1994-08-01 11:34:53 +00002858#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002859PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002860"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002861Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002862
Barry Warsaw53699e91996-12-10 23:23:01 +00002863static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002864posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002865{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002866 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002867 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002868
Barry Warsaw53699e91996-12-10 23:23:01 +00002869 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002870 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002871 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002872 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002873 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002874 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002875 u.sysname,
2876 u.nodename,
2877 u.release,
2878 u.version,
2879 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002880}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002881#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002882
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002883static int
2884extract_time(PyObject *t, long* sec, long* usec)
2885{
2886 long intval;
2887 if (PyFloat_Check(t)) {
2888 double tval = PyFloat_AsDouble(t);
Christian Heimes90aa7642007-12-19 02:45:37 +00002889 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002890 if (!intobj)
2891 return -1;
Christian Heimes217cfd12007-12-02 14:31:20 +00002892 intval = PyLong_AsLong(intobj);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002893 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002894 if (intval == -1 && PyErr_Occurred())
2895 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002896 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002897 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002898 if (*usec < 0)
2899 /* If rounding gave us a negative number,
2900 truncate. */
2901 *usec = 0;
2902 return 0;
2903 }
Christian Heimes217cfd12007-12-02 14:31:20 +00002904 intval = PyLong_AsLong(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002905 if (intval == -1 && PyErr_Occurred())
2906 return -1;
2907 *sec = intval;
2908 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002909 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002910}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002911
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002912PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002913"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002914utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002915Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002916second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002917
Barry Warsaw53699e91996-12-10 23:23:01 +00002918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002919posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002920{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002921#ifdef Py_WIN_WIDE_FILENAMES
2922 PyObject *arg;
2923 PyUnicodeObject *obwpath;
2924 wchar_t *wpath = NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002925 PyObject *oapath;
2926 char *apath;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002927 HANDLE hFile;
2928 long atimesec, mtimesec, ausec, musec;
2929 FILETIME atime, mtime;
2930 PyObject *result = NULL;
2931
2932 if (unicode_file_names()) {
2933 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2934 wpath = PyUnicode_AS_UNICODE(obwpath);
2935 Py_BEGIN_ALLOW_THREADS
2936 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002937 NULL, OPEN_EXISTING,
2938 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002939 Py_END_ALLOW_THREADS
2940 if (hFile == INVALID_HANDLE_VALUE)
2941 return win32_error_unicode("utime", wpath);
2942 } else
2943 /* Drop the argument parsing error as narrow strings
2944 are also valid. */
2945 PyErr_Clear();
2946 }
2947 if (!wpath) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00002948 if (!PyArg_ParseTuple(args, "O&O:utime",
2949 PyUnicode_FSConverter, &oapath, &arg))
Thomas Wouters477c8d52006-05-27 19:21:47 +00002950 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002951 apath = bytes2str(oapath, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002952 Py_BEGIN_ALLOW_THREADS
2953 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002954 NULL, OPEN_EXISTING,
2955 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002956 Py_END_ALLOW_THREADS
2957 if (hFile == INVALID_HANDLE_VALUE) {
2958 win32_error("utime", apath);
Martin v. Löwis011e8422009-05-05 04:43:17 +00002959 release_bytes(oapath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002960 return NULL;
2961 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00002962 release_bytes(oapath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002963 }
2964
2965 if (arg == Py_None) {
2966 SYSTEMTIME now;
2967 GetSystemTime(&now);
2968 if (!SystemTimeToFileTime(&now, &mtime) ||
2969 !SystemTimeToFileTime(&now, &atime)) {
2970 win32_error("utime", NULL);
2971 goto done;
2972 }
2973 }
2974 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2975 PyErr_SetString(PyExc_TypeError,
2976 "utime() arg 2 must be a tuple (atime, mtime)");
2977 goto done;
2978 }
2979 else {
2980 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2981 &atimesec, &ausec) == -1)
2982 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002983 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002984 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2985 &mtimesec, &musec) == -1)
2986 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002987 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002988 }
2989 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2990 /* Avoid putting the file name into the error here,
2991 as that may confuse the user into believing that
2992 something is wrong with the file, when it also
2993 could be the time stamp that gives a problem. */
2994 win32_error("utime", NULL);
2995 }
2996 Py_INCREF(Py_None);
2997 result = Py_None;
2998done:
2999 CloseHandle(hFile);
3000 return result;
3001#else /* Py_WIN_WIDE_FILENAMES */
3002
Martin v. Löwis011e8422009-05-05 04:43:17 +00003003 PyObject *opath;
3004 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003005 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00003006 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00003007 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003008
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003009#if defined(HAVE_UTIMES)
3010 struct timeval buf[2];
3011#define ATIME buf[0].tv_sec
3012#define MTIME buf[1].tv_sec
3013#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003014/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003015 struct utimbuf buf;
3016#define ATIME buf.actime
3017#define MTIME buf.modtime
3018#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003019#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003020 time_t buf[2];
3021#define ATIME buf[0]
3022#define MTIME buf[1]
3023#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003024#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003025
Mark Hammond817c9292003-12-03 01:22:38 +00003026
Martin v. Löwis011e8422009-05-05 04:43:17 +00003027 if (!PyArg_ParseTuple(args, "O&O:utime",
3028 PyUnicode_FSConverter, &opath, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003029 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003030 path = bytes2str(opath, 1);
Barry Warsaw3cef8562000-05-01 16:17:24 +00003031 if (arg == Py_None) {
3032 /* optional time values not given */
3033 Py_BEGIN_ALLOW_THREADS
3034 res = utime(path, NULL);
3035 Py_END_ALLOW_THREADS
3036 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003037 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00003038 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003039 "utime() arg 2 must be a tuple (atime, mtime)");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003040 release_bytes(opath);
Barry Warsaw3cef8562000-05-01 16:17:24 +00003041 return NULL;
3042 }
3043 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003044 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00003045 &atime, &ausec) == -1) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003046 release_bytes(opath);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003047 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00003048 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003049 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00003050 &mtime, &musec) == -1) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003051 release_bytes(opath);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003052 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00003053 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00003054 ATIME = atime;
3055 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003056#ifdef HAVE_UTIMES
3057 buf[0].tv_usec = ausec;
3058 buf[1].tv_usec = musec;
3059 Py_BEGIN_ALLOW_THREADS
3060 res = utimes(path, buf);
3061 Py_END_ALLOW_THREADS
3062#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00003063 Py_BEGIN_ALLOW_THREADS
3064 res = utime(path, UTIME_ARG);
3065 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003066#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00003067 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00003068 if (res < 0) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003069 return posix_error_with_allocated_filename(opath);
Mark Hammond2d5914b2004-05-04 08:10:37 +00003070 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00003071 release_bytes(opath);
Barry Warsaw53699e91996-12-10 23:23:01 +00003072 Py_INCREF(Py_None);
3073 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003074#undef UTIME_ARG
3075#undef ATIME
3076#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00003077#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003078}
3079
Guido van Rossum85e3b011991-06-03 12:42:10 +00003080
Guido van Rossum3b066191991-06-04 19:40:25 +00003081/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003083PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003084"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003085Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003086
Barry Warsaw53699e91996-12-10 23:23:01 +00003087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003088posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003089{
3090 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003091 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003092 return NULL;
3093 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00003094 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003095}
3096
Martin v. Löwis114619e2002-10-07 06:44:21 +00003097#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3098static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003099free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003100{
Martin v. Löwis725507b2006-03-07 12:08:51 +00003101 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00003102 for (i = 0; i < count; i++)
3103 PyMem_Free(array[i]);
3104 PyMem_DEL(array);
3105}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003106
3107int fsconvert_strdup(PyObject *o, char**out)
3108{
3109 PyObject *bytes;
3110 Py_ssize_t size;
3111 if (!PyUnicode_FSConverter(o, &bytes))
3112 return 0;
3113 size = PyObject_Size(bytes);
3114 *out = PyMem_Malloc(size+1);
3115 if (!*out)
3116 return 0;
3117 /* Don't lock bytes, as we hold the GIL */
3118 memcpy(*out, bytes2str(bytes, 0), size+1);
3119 Py_DECREF(bytes);
3120 return 1;
3121}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003122#endif
3123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003124
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003125#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003126PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003127"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003128Execute an executable path with arguments, replacing current process.\n\
3129\n\
3130 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003131 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003132
Barry Warsaw53699e91996-12-10 23:23:01 +00003133static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003134posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003135{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003136 PyObject *opath;
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003137 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003138 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003139 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003140 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003141 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003142
Guido van Rossum89b33251993-10-22 14:26:06 +00003143 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00003144 argv is a list or tuple of strings. */
3145
Martin v. Löwis011e8422009-05-05 04:43:17 +00003146 if (!PyArg_ParseTuple(args, "O&O:execv",
3147 PyUnicode_FSConverter,
3148 &opath, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003149 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003150 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00003151 if (PyList_Check(argv)) {
3152 argc = PyList_Size(argv);
3153 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003154 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003155 else if (PyTuple_Check(argv)) {
3156 argc = PyTuple_Size(argv);
3157 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003158 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003159 else {
Fred Drake661ea262000-10-24 19:57:45 +00003160 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003161 release_bytes(opath);
Guido van Rossum50422b42000-04-26 20:34:28 +00003162 return NULL;
3163 }
Thomas Heller6790d602007-08-30 17:15:14 +00003164 if (argc < 1) {
3165 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003166 release_bytes(opath);
Thomas Heller6790d602007-08-30 17:15:14 +00003167 return NULL;
3168 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003169
Barry Warsaw53699e91996-12-10 23:23:01 +00003170 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003171 if (argvlist == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003172 release_bytes(opath);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003173 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003174 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003175 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003176 if (!fsconvert_strdup((*getitem)(argv, i),
3177 &argvlist[i])) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003178 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00003179 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003180 "execv() arg 2 must contain only strings");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003181 release_bytes(opath);
Guido van Rossum50422b42000-04-26 20:34:28 +00003182 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003183
Guido van Rossum85e3b011991-06-03 12:42:10 +00003184 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003185 }
3186 argvlist[argc] = NULL;
3187
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003188 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003189
Guido van Rossum85e3b011991-06-03 12:42:10 +00003190 /* If we get here it's definitely an error */
3191
Martin v. Löwis114619e2002-10-07 06:44:21 +00003192 free_string_array(argvlist, argc);
Martin v. Löwis011e8422009-05-05 04:43:17 +00003193 release_bytes(opath);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003194 return posix_error();
3195}
3196
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003198PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003199"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003200Execute a path with arguments and environment, replacing current process.\n\
3201\n\
3202 path: path of executable file\n\
3203 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003204 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003205
Barry Warsaw53699e91996-12-10 23:23:01 +00003206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003207posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003208{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003209 PyObject *opath;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003210 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003211 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003212 char **argvlist;
3213 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003214 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003215 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003216 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003217 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003218
3219 /* execve has three arguments: (path, argv, env), where
3220 argv is a list or tuple of strings and env is a dictionary
3221 like posix.environ. */
3222
Martin v. Löwis011e8422009-05-05 04:43:17 +00003223 if (!PyArg_ParseTuple(args, "O&OO:execve",
3224 PyUnicode_FSConverter,
3225 &opath, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003226 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003227 path = bytes2str(opath, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00003228 if (PyList_Check(argv)) {
3229 argc = PyList_Size(argv);
3230 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003231 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003232 else if (PyTuple_Check(argv)) {
3233 argc = PyTuple_Size(argv);
3234 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003235 }
3236 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003237 PyErr_SetString(PyExc_TypeError,
3238 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003239 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003240 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003241 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003242 PyErr_SetString(PyExc_TypeError,
3243 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003244 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003245 }
3246
Barry Warsaw53699e91996-12-10 23:23:01 +00003247 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003248 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003249 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003250 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003251 }
3252 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003253 if (!fsconvert_strdup((*getitem)(argv, i),
3254 &argvlist[i]))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003255 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003256 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003257 goto fail_1;
3258 }
3259 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003260 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003261 argvlist[argc] = NULL;
3262
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003263 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003264 if (i < 0)
3265 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003266 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003267 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003268 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003269 goto fail_1;
3270 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003271 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003272 keys = PyMapping_Keys(env);
3273 vals = PyMapping_Values(env);
3274 if (!keys || !vals)
3275 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003276 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3277 PyErr_SetString(PyExc_TypeError,
3278 "execve(): env.keys() or env.values() is not a list");
3279 goto fail_2;
3280 }
Tim Peters5aa91602002-01-30 05:46:57 +00003281
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003282 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003283 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003284 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003285
3286 key = PyList_GetItem(keys, pos);
3287 val = PyList_GetItem(vals, pos);
3288 if (!key || !val)
3289 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003290
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003291 if (!PyArg_Parse(
3292 key,
3293 "s;execve() arg 3 contains a non-string key",
3294 &k) ||
3295 !PyArg_Parse(
3296 val,
3297 "s;execve() arg 3 contains a non-string value",
3298 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003299 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003300 goto fail_2;
3301 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003302
3303#if defined(PYOS_OS2)
3304 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3305 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3306#endif
Christian Heimes830a4bc2007-11-22 07:43:40 +00003307 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003308 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003309 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003310 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003311 goto fail_2;
3312 }
Tim Petersc8996f52001-12-03 20:41:00 +00003313 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003314 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003315#if defined(PYOS_OS2)
3316 }
3317#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003318 }
3319 envlist[envc] = 0;
3320
3321 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003322
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003323 /* If we get here it's definitely an error */
3324
3325 (void) posix_error();
3326
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003327 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003328 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003329 PyMem_DEL(envlist[envc]);
3330 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003331 fail_1:
3332 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003333 Py_XDECREF(vals);
3334 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003335 fail_0:
Martin v. Löwis011e8422009-05-05 04:43:17 +00003336 release_bytes(opath);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003337 return NULL;
3338}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003339#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003341
Guido van Rossuma1065681999-01-25 23:20:23 +00003342#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003343PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003344"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003345Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003346\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003347 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003348 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003349 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003350
3351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003352posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003353{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003354 PyObject *opath;
Guido van Rossuma1065681999-01-25 23:20:23 +00003355 char *path;
3356 PyObject *argv;
3357 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003358 int mode, i;
3359 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003360 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003361 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003362
3363 /* spawnv has three arguments: (mode, path, argv), where
3364 argv is a list or tuple of strings. */
3365
Martin v. Löwis011e8422009-05-05 04:43:17 +00003366 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3367 PyUnicode_FSConverter,
3368 &opath, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003369 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003370 path = bytes2str(opath, 1);
Guido van Rossuma1065681999-01-25 23:20:23 +00003371 if (PyList_Check(argv)) {
3372 argc = PyList_Size(argv);
3373 getitem = PyList_GetItem;
3374 }
3375 else if (PyTuple_Check(argv)) {
3376 argc = PyTuple_Size(argv);
3377 getitem = PyTuple_GetItem;
3378 }
3379 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003380 PyErr_SetString(PyExc_TypeError,
3381 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003382 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003383 return NULL;
3384 }
3385
3386 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003387 if (argvlist == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003388 release_bytes(opath);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003389 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003390 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003391 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003392 if (!fsconvert_strdup((*getitem)(argv, i),
3393 &argvlist[i])) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003394 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003395 PyErr_SetString(
3396 PyExc_TypeError,
3397 "spawnv() arg 2 must contain only strings");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003398 release_bytes(opath);
Fred Drake137507e2000-06-01 02:02:46 +00003399 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003400 }
3401 }
3402 argvlist[argc] = NULL;
3403
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003404#if defined(PYOS_OS2) && defined(PYCC_GCC)
3405 Py_BEGIN_ALLOW_THREADS
3406 spawnval = spawnv(mode, path, argvlist);
3407 Py_END_ALLOW_THREADS
3408#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003409 if (mode == _OLD_P_OVERLAY)
3410 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003411
Tim Peters25059d32001-12-07 20:35:43 +00003412 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003413 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003414 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003415#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003416
Martin v. Löwis114619e2002-10-07 06:44:21 +00003417 free_string_array(argvlist, argc);
Martin v. Löwis011e8422009-05-05 04:43:17 +00003418 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003419
Fred Drake699f3522000-06-29 21:12:41 +00003420 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003421 return posix_error();
3422 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003423#if SIZEOF_LONG == SIZEOF_VOID_P
3424 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003425#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003426 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003427#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003428}
3429
3430
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003431PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003432"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003433Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003434\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003435 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003436 path: path of executable file\n\
3437 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003438 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003439
3440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003441posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003442{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003443 PyObject *opath;
Guido van Rossuma1065681999-01-25 23:20:23 +00003444 char *path;
3445 PyObject *argv, *env;
3446 char **argvlist;
3447 char **envlist;
3448 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003449 int mode, pos, envc;
3450 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003451 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003452 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003453 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003454
3455 /* spawnve has four arguments: (mode, path, argv, env), where
3456 argv is a list or tuple of strings and env is a dictionary
3457 like posix.environ. */
3458
Martin v. Löwis011e8422009-05-05 04:43:17 +00003459 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3460 PyUnicode_FSConverter,
3461 &opath, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003462 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003463 path = bytes2str(opath, 1);
Guido van Rossuma1065681999-01-25 23:20:23 +00003464 if (PyList_Check(argv)) {
3465 argc = PyList_Size(argv);
3466 getitem = PyList_GetItem;
3467 }
3468 else if (PyTuple_Check(argv)) {
3469 argc = PyTuple_Size(argv);
3470 getitem = PyTuple_GetItem;
3471 }
3472 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003473 PyErr_SetString(PyExc_TypeError,
3474 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003475 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003476 }
3477 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003478 PyErr_SetString(PyExc_TypeError,
3479 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003480 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003481 }
3482
3483 argvlist = PyMem_NEW(char *, argc+1);
3484 if (argvlist == NULL) {
3485 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003486 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003487 }
3488 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003489 if (!fsconvert_strdup((*getitem)(argv, i),
3490 &argvlist[i]))
Guido van Rossuma1065681999-01-25 23:20:23 +00003491 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003492 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003493 goto fail_1;
3494 }
3495 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003496 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003497 argvlist[argc] = NULL;
3498
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003499 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003500 if (i < 0)
3501 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003502 envlist = PyMem_NEW(char *, i + 1);
3503 if (envlist == NULL) {
3504 PyErr_NoMemory();
3505 goto fail_1;
3506 }
3507 envc = 0;
3508 keys = PyMapping_Keys(env);
3509 vals = PyMapping_Values(env);
3510 if (!keys || !vals)
3511 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003512 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3513 PyErr_SetString(PyExc_TypeError,
3514 "spawnve(): env.keys() or env.values() is not a list");
3515 goto fail_2;
3516 }
Tim Peters5aa91602002-01-30 05:46:57 +00003517
Guido van Rossuma1065681999-01-25 23:20:23 +00003518 for (pos = 0; pos < i; pos++) {
3519 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003520 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003521
3522 key = PyList_GetItem(keys, pos);
3523 val = PyList_GetItem(vals, pos);
3524 if (!key || !val)
3525 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003526
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003527 if (!PyArg_Parse(
3528 key,
3529 "s;spawnve() arg 3 contains a non-string key",
3530 &k) ||
3531 !PyArg_Parse(
3532 val,
3533 "s;spawnve() arg 3 contains a non-string value",
3534 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003535 {
3536 goto fail_2;
3537 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003538 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003539 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003540 if (p == NULL) {
3541 PyErr_NoMemory();
3542 goto fail_2;
3543 }
Tim Petersc8996f52001-12-03 20:41:00 +00003544 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003545 envlist[envc++] = p;
3546 }
3547 envlist[envc] = 0;
3548
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003549#if defined(PYOS_OS2) && defined(PYCC_GCC)
3550 Py_BEGIN_ALLOW_THREADS
3551 spawnval = spawnve(mode, path, argvlist, envlist);
3552 Py_END_ALLOW_THREADS
3553#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003554 if (mode == _OLD_P_OVERLAY)
3555 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003556
3557 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003558 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003559 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003560#endif
Tim Peters25059d32001-12-07 20:35:43 +00003561
Fred Drake699f3522000-06-29 21:12:41 +00003562 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003563 (void) posix_error();
3564 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003565#if SIZEOF_LONG == SIZEOF_VOID_P
3566 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003567#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003568 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003569#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003570
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003571 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003572 while (--envc >= 0)
3573 PyMem_DEL(envlist[envc]);
3574 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003575 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003576 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003577 Py_XDECREF(vals);
3578 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003579 fail_0:
Martin v. Löwis011e8422009-05-05 04:43:17 +00003580 release_bytes(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003581 return res;
3582}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003583
3584/* OS/2 supports spawnvp & spawnvpe natively */
3585#if defined(PYOS_OS2)
3586PyDoc_STRVAR(posix_spawnvp__doc__,
3587"spawnvp(mode, file, args)\n\n\
3588Execute the program 'file' in a new process, using the environment\n\
3589search path to find the file.\n\
3590\n\
3591 mode: mode of process creation\n\
3592 file: executable file name\n\
3593 args: tuple or list of strings");
3594
3595static PyObject *
3596posix_spawnvp(PyObject *self, PyObject *args)
3597{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003598 PyObject *opath;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003599 char *path;
3600 PyObject *argv;
3601 char **argvlist;
3602 int mode, i, argc;
3603 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003604 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003605
3606 /* spawnvp has three arguments: (mode, path, argv), where
3607 argv is a list or tuple of strings. */
3608
Martin v. Löwis011e8422009-05-05 04:43:17 +00003609 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3610 PyUnicode_FSConverter,
3611 &opath, &argv))
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003612 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003613 path = bytes2str(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003614 if (PyList_Check(argv)) {
3615 argc = PyList_Size(argv);
3616 getitem = PyList_GetItem;
3617 }
3618 else if (PyTuple_Check(argv)) {
3619 argc = PyTuple_Size(argv);
3620 getitem = PyTuple_GetItem;
3621 }
3622 else {
3623 PyErr_SetString(PyExc_TypeError,
3624 "spawnvp() arg 2 must be a tuple or list");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003625 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003626 return NULL;
3627 }
3628
3629 argvlist = PyMem_NEW(char *, argc+1);
3630 if (argvlist == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003631 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003632 return PyErr_NoMemory();
3633 }
3634 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003635 if (!fsconvert_strdup((*getitem)(argv, i),
3636 &argvlist[i])) {
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003637 free_string_array(argvlist, i);
3638 PyErr_SetString(
3639 PyExc_TypeError,
3640 "spawnvp() arg 2 must contain only strings");
Martin v. Löwis011e8422009-05-05 04:43:17 +00003641 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003642 return NULL;
3643 }
3644 }
3645 argvlist[argc] = NULL;
3646
3647 Py_BEGIN_ALLOW_THREADS
3648#if defined(PYCC_GCC)
3649 spawnval = spawnvp(mode, path, argvlist);
3650#else
3651 spawnval = _spawnvp(mode, path, argvlist);
3652#endif
3653 Py_END_ALLOW_THREADS
3654
3655 free_string_array(argvlist, argc);
Martin v. Löwis011e8422009-05-05 04:43:17 +00003656 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003657
3658 if (spawnval == -1)
3659 return posix_error();
3660 else
3661 return Py_BuildValue("l", (long) spawnval);
3662}
3663
3664
3665PyDoc_STRVAR(posix_spawnvpe__doc__,
3666"spawnvpe(mode, file, args, env)\n\n\
3667Execute the program 'file' in a new process, using the environment\n\
3668search path to find the file.\n\
3669\n\
3670 mode: mode of process creation\n\
3671 file: executable file name\n\
3672 args: tuple or list of arguments\n\
3673 env: dictionary of strings mapping to strings");
3674
3675static PyObject *
3676posix_spawnvpe(PyObject *self, PyObject *args)
3677{
Martin v. Löwis011e8422009-05-05 04:43:17 +00003678 PyObject *opath
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003679 char *path;
3680 PyObject *argv, *env;
3681 char **argvlist;
3682 char **envlist;
3683 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3684 int mode, i, pos, argc, envc;
3685 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003686 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003687 int lastarg = 0;
3688
3689 /* spawnvpe has four arguments: (mode, path, argv, env), where
3690 argv is a list or tuple of strings and env is a dictionary
3691 like posix.environ. */
3692
3693 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
Martin v. Löwis011e8422009-05-05 04:43:17 +00003694 PyUnicode_FSConverter,
3695 &opath, &argv, &env))
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003696 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003697 path = bytes2str(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003698 if (PyList_Check(argv)) {
3699 argc = PyList_Size(argv);
3700 getitem = PyList_GetItem;
3701 }
3702 else if (PyTuple_Check(argv)) {
3703 argc = PyTuple_Size(argv);
3704 getitem = PyTuple_GetItem;
3705 }
3706 else {
3707 PyErr_SetString(PyExc_TypeError,
3708 "spawnvpe() arg 2 must be a tuple or list");
3709 goto fail_0;
3710 }
3711 if (!PyMapping_Check(env)) {
3712 PyErr_SetString(PyExc_TypeError,
3713 "spawnvpe() arg 3 must be a mapping object");
3714 goto fail_0;
3715 }
3716
3717 argvlist = PyMem_NEW(char *, argc+1);
3718 if (argvlist == NULL) {
3719 PyErr_NoMemory();
3720 goto fail_0;
3721 }
3722 for (i = 0; i < argc; i++) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00003723 if (!fsconvert_strdup((*getitem)(argv, i),
3724 &argvlist[i]))
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003725 {
3726 lastarg = i;
3727 goto fail_1;
3728 }
3729 }
3730 lastarg = argc;
3731 argvlist[argc] = NULL;
3732
3733 i = PyMapping_Size(env);
3734 if (i < 0)
3735 goto fail_1;
3736 envlist = PyMem_NEW(char *, i + 1);
3737 if (envlist == NULL) {
3738 PyErr_NoMemory();
3739 goto fail_1;
3740 }
3741 envc = 0;
3742 keys = PyMapping_Keys(env);
3743 vals = PyMapping_Values(env);
3744 if (!keys || !vals)
3745 goto fail_2;
3746 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3747 PyErr_SetString(PyExc_TypeError,
3748 "spawnvpe(): env.keys() or env.values() is not a list");
3749 goto fail_2;
3750 }
3751
3752 for (pos = 0; pos < i; pos++) {
3753 char *p, *k, *v;
3754 size_t len;
3755
3756 key = PyList_GetItem(keys, pos);
3757 val = PyList_GetItem(vals, pos);
3758 if (!key || !val)
3759 goto fail_2;
3760
3761 if (!PyArg_Parse(
3762 key,
3763 "s;spawnvpe() arg 3 contains a non-string key",
3764 &k) ||
3765 !PyArg_Parse(
3766 val,
3767 "s;spawnvpe() arg 3 contains a non-string value",
3768 &v))
3769 {
3770 goto fail_2;
3771 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003772 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003773 p = PyMem_NEW(char, len);
3774 if (p == NULL) {
3775 PyErr_NoMemory();
3776 goto fail_2;
3777 }
3778 PyOS_snprintf(p, len, "%s=%s", k, v);
3779 envlist[envc++] = p;
3780 }
3781 envlist[envc] = 0;
3782
3783 Py_BEGIN_ALLOW_THREADS
3784#if defined(PYCC_GCC)
Christian Heimes292d3512008-02-03 16:51:08 +00003785 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003786#else
Christian Heimes292d3512008-02-03 16:51:08 +00003787 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003788#endif
3789 Py_END_ALLOW_THREADS
3790
3791 if (spawnval == -1)
3792 (void) posix_error();
3793 else
3794 res = Py_BuildValue("l", (long) spawnval);
3795
3796 fail_2:
3797 while (--envc >= 0)
3798 PyMem_DEL(envlist[envc]);
3799 PyMem_DEL(envlist);
3800 fail_1:
3801 free_string_array(argvlist, lastarg);
3802 Py_XDECREF(vals);
3803 Py_XDECREF(keys);
3804 fail_0:
Martin v. Löwis011e8422009-05-05 04:43:17 +00003805 release_bytes(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003806 return res;
3807}
3808#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003809#endif /* HAVE_SPAWNV */
3810
3811
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003812#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003813PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003814"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003815Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3816\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003817Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003818
3819static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003820posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003821{
Christian Heimes400adb02008-02-01 08:12:03 +00003822 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003823 if (pid == -1)
3824 return posix_error();
Georg Brandl2ee470f2008-07-16 12:55:28 +00003825 if (pid == 0)
3826 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003827 return PyLong_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003828}
3829#endif
3830
3831
Guido van Rossumad0ee831995-03-01 10:34:45 +00003832#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003833PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003834"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003835Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003836Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003837
Barry Warsaw53699e91996-12-10 23:23:01 +00003838static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003839posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003840{
Christian Heimes400adb02008-02-01 08:12:03 +00003841 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003842 if (pid == -1)
3843 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003844 if (pid == 0)
3845 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003846 return PyLong_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003847}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003848#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003849
Neal Norwitzb59798b2003-03-21 01:43:31 +00003850/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003851/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3852#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003853#define DEV_PTY_FILE "/dev/ptc"
3854#define HAVE_DEV_PTMX
3855#else
3856#define DEV_PTY_FILE "/dev/ptmx"
3857#endif
3858
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003859#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003860#ifdef HAVE_PTY_H
3861#include <pty.h>
3862#else
3863#ifdef HAVE_LIBUTIL_H
3864#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003865#endif /* HAVE_LIBUTIL_H */
3866#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003867#ifdef HAVE_STROPTS_H
3868#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003869#endif
3870#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003871
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003872#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003873PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003874"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003875Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003876
3877static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003878posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003879{
3880 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003881#ifndef HAVE_OPENPTY
3882 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003883#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003884#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003885 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003886#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003887 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003888#endif
3889#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003890
Thomas Wouters70c21a12000-07-14 14:28:33 +00003891#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003892 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3893 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003894#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003895 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3896 if (slave_name == NULL)
3897 return posix_error();
3898
3899 slave_fd = open(slave_name, O_RDWR);
3900 if (slave_fd < 0)
3901 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003902#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003903 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003904 if (master_fd < 0)
3905 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003906 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003907 /* change permission of slave */
3908 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003909 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003910 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003911 }
3912 /* unlock slave */
3913 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003914 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003915 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003916 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003917 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003918 slave_name = ptsname(master_fd); /* get name of slave */
3919 if (slave_name == NULL)
3920 return posix_error();
3921 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3922 if (slave_fd < 0)
3923 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003924#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003925 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3926 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003927#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003928 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003929#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003930#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003931#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003932
Fred Drake8cef4cf2000-06-28 16:40:38 +00003933 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003934
Fred Drake8cef4cf2000-06-28 16:40:38 +00003935}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003936#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003937
3938#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003939PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003940"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003941Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3942Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003943To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003944
3945static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003946posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003947{
Christian Heimes400adb02008-02-01 08:12:03 +00003948 int master_fd = -1;
3949 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003950
Fred Drake8cef4cf2000-06-28 16:40:38 +00003951 pid = forkpty(&master_fd, NULL, NULL, NULL);
3952 if (pid == -1)
3953 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003954 if (pid == 0)
3955 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003956 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003957}
3958#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003959
Guido van Rossumad0ee831995-03-01 10:34:45 +00003960#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003961PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003962"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003963Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003964
Barry Warsaw53699e91996-12-10 23:23:01 +00003965static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003966posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003967{
Christian Heimes217cfd12007-12-02 14:31:20 +00003968 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003969}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003970#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003972
Guido van Rossumad0ee831995-03-01 10:34:45 +00003973#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003974PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003975"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003976Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003977
Barry Warsaw53699e91996-12-10 23:23:01 +00003978static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003979posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003980{
Christian Heimes217cfd12007-12-02 14:31:20 +00003981 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003982}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003983#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003984
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003985
Guido van Rossumad0ee831995-03-01 10:34:45 +00003986#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003987PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003988"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003989Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003990
Barry Warsaw53699e91996-12-10 23:23:01 +00003991static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003992posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003993{
Christian Heimes217cfd12007-12-02 14:31:20 +00003994 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003995}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003996#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003997
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003998
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003999PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004000"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004001Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004002
Barry Warsaw53699e91996-12-10 23:23:01 +00004003static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004004posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004005{
Christian Heimes217cfd12007-12-02 14:31:20 +00004006 return PyLong_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004007}
4008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004009
Fred Drakec9680921999-12-13 16:37:25 +00004010#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004011PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004012"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004013Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004014
4015static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004016posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004017{
4018 PyObject *result = NULL;
4019
Fred Drakec9680921999-12-13 16:37:25 +00004020#ifdef NGROUPS_MAX
4021#define MAX_GROUPS NGROUPS_MAX
4022#else
4023 /* defined to be 16 on Solaris7, so this should be a small number */
4024#define MAX_GROUPS 64
4025#endif
4026 gid_t grouplist[MAX_GROUPS];
4027 int n;
4028
4029 n = getgroups(MAX_GROUPS, grouplist);
4030 if (n < 0)
4031 posix_error();
4032 else {
4033 result = PyList_New(n);
4034 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00004035 int i;
4036 for (i = 0; i < n; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00004037 PyObject *o = PyLong_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00004038 if (o == NULL) {
4039 Py_DECREF(result);
4040 result = NULL;
4041 break;
4042 }
4043 PyList_SET_ITEM(result, i, o);
4044 }
4045 }
4046 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004047
Fred Drakec9680921999-12-13 16:37:25 +00004048 return result;
4049}
4050#endif
4051
Martin v. Löwis606edc12002-06-13 21:09:11 +00004052#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004053PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004054"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004055Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004056
4057static PyObject *
4058posix_getpgid(PyObject *self, PyObject *args)
4059{
4060 int pid, pgid;
4061 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
4062 return NULL;
4063 pgid = getpgid(pid);
4064 if (pgid < 0)
4065 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004066 return PyLong_FromLong((long)pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004067}
4068#endif /* HAVE_GETPGID */
4069
4070
Guido van Rossumb6775db1994-08-01 11:34:53 +00004071#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004072PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004073"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004074Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004075
Barry Warsaw53699e91996-12-10 23:23:01 +00004076static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004077posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004078{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004079#ifdef GETPGRP_HAVE_ARG
Christian Heimes217cfd12007-12-02 14:31:20 +00004080 return PyLong_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004081#else /* GETPGRP_HAVE_ARG */
Christian Heimes217cfd12007-12-02 14:31:20 +00004082 return PyLong_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004083#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004084}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004085#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004087
Guido van Rossumb6775db1994-08-01 11:34:53 +00004088#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004089PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004090"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004091Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004092
Barry Warsaw53699e91996-12-10 23:23:01 +00004093static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004094posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004095{
Guido van Rossum64933891994-10-20 21:56:42 +00004096#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00004097 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004098#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004099 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004100#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00004101 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004102 Py_INCREF(Py_None);
4103 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004104}
4105
Guido van Rossumb6775db1994-08-01 11:34:53 +00004106#endif /* HAVE_SETPGRP */
4107
Guido van Rossumad0ee831995-03-01 10:34:45 +00004108#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004109PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004110"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004111Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004112
Barry Warsaw53699e91996-12-10 23:23:01 +00004113static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004114posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004115{
Christian Heimes217cfd12007-12-02 14:31:20 +00004116 return PyLong_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004117}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004118#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004120
Fred Drake12c6e2d1999-12-14 21:25:03 +00004121#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004122PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004123"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004124Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004125
4126static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004127posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004128{
Neal Norwitze241ce82003-02-17 18:17:05 +00004129 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00004130 char *name;
4131 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004132
Fred Drakea30680b2000-12-06 21:24:28 +00004133 errno = 0;
4134 name = getlogin();
4135 if (name == NULL) {
4136 if (errno)
4137 posix_error();
4138 else
4139 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00004140 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00004141 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00004142 else
Neal Norwitz93c56822007-08-26 07:10:06 +00004143 result = PyUnicode_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00004144 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004145
Fred Drake12c6e2d1999-12-14 21:25:03 +00004146 return result;
4147}
4148#endif
4149
Guido van Rossumad0ee831995-03-01 10:34:45 +00004150#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004151PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004152"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004153Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004154
Barry Warsaw53699e91996-12-10 23:23:01 +00004155static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004156posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004157{
Christian Heimes217cfd12007-12-02 14:31:20 +00004158 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004159}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004160#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004161
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004162
Guido van Rossumad0ee831995-03-01 10:34:45 +00004163#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004164PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004165"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004166Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004167
Barry Warsaw53699e91996-12-10 23:23:01 +00004168static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004169posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004170{
Christian Heimes292d3512008-02-03 16:51:08 +00004171 pid_t pid;
4172 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004173 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00004174 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004175#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004176 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4177 APIRET rc;
4178 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004179 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004180
4181 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4182 APIRET rc;
4183 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004184 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004185
4186 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004187 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004188#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004189 if (kill(pid, sig) == -1)
4190 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004191#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004192 Py_INCREF(Py_None);
4193 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004194}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004195#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004196
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004197#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004198PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004199"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004200Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004201
4202static PyObject *
4203posix_killpg(PyObject *self, PyObject *args)
4204{
4205 int pgid, sig;
4206 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4207 return NULL;
4208 if (killpg(pgid, sig) == -1)
4209 return posix_error();
4210 Py_INCREF(Py_None);
4211 return Py_None;
4212}
4213#endif
4214
Guido van Rossumc0125471996-06-28 18:55:32 +00004215#ifdef HAVE_PLOCK
4216
4217#ifdef HAVE_SYS_LOCK_H
4218#include <sys/lock.h>
4219#endif
4220
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004221PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004222"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004223Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004224
Barry Warsaw53699e91996-12-10 23:23:01 +00004225static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004226posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004227{
4228 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004229 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004230 return NULL;
4231 if (plock(op) == -1)
4232 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004233 Py_INCREF(Py_None);
4234 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004235}
4236#endif
4237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004238
Guido van Rossum3b066191991-06-04 19:40:25 +00004239
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004240
Guido van Rossumb6775db1994-08-01 11:34:53 +00004241#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004242PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004243"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004244Set the current process's user id.");
4245
Barry Warsaw53699e91996-12-10 23:23:01 +00004246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004247posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004248{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004249 long uid_arg;
4250 uid_t uid;
4251 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004252 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004253 uid = uid_arg;
4254 if (uid != uid_arg) {
4255 PyErr_SetString(PyExc_OverflowError, "user id too big");
4256 return NULL;
4257 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004258 if (setuid(uid) < 0)
4259 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004260 Py_INCREF(Py_None);
4261 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004262}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004263#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004265
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004266#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004267PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004268"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004269Set the current process's effective user id.");
4270
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004271static PyObject *
4272posix_seteuid (PyObject *self, PyObject *args)
4273{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004274 long euid_arg;
4275 uid_t euid;
4276 if (!PyArg_ParseTuple(args, "l", &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004277 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004278 euid = euid_arg;
4279 if (euid != euid_arg) {
4280 PyErr_SetString(PyExc_OverflowError, "user id too big");
4281 return NULL;
4282 }
4283 if (seteuid(euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004284 return posix_error();
4285 } else {
4286 Py_INCREF(Py_None);
4287 return Py_None;
4288 }
4289}
4290#endif /* HAVE_SETEUID */
4291
4292#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004293PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004294"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004295Set the current process's effective group id.");
4296
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004297static PyObject *
4298posix_setegid (PyObject *self, PyObject *args)
4299{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004300 long egid_arg;
4301 gid_t egid;
4302 if (!PyArg_ParseTuple(args, "l", &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004303 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004304 egid = egid_arg;
4305 if (egid != egid_arg) {
4306 PyErr_SetString(PyExc_OverflowError, "group id too big");
4307 return NULL;
4308 }
4309 if (setegid(egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004310 return posix_error();
4311 } else {
4312 Py_INCREF(Py_None);
4313 return Py_None;
4314 }
4315}
4316#endif /* HAVE_SETEGID */
4317
4318#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004319PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004320"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004321Set the current process's real and effective user ids.");
4322
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004323static PyObject *
4324posix_setreuid (PyObject *self, PyObject *args)
4325{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004326 long ruid_arg, euid_arg;
4327 uid_t ruid, euid;
4328 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004329 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004330 ruid = ruid_arg;
4331 euid = euid_arg;
4332 if (euid != euid_arg || ruid != ruid_arg) {
4333 PyErr_SetString(PyExc_OverflowError, "user id too big");
4334 return NULL;
4335 }
4336 if (setreuid(ruid, euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004337 return posix_error();
4338 } else {
4339 Py_INCREF(Py_None);
4340 return Py_None;
4341 }
4342}
4343#endif /* HAVE_SETREUID */
4344
4345#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004346PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004347"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004348Set the current process's real and effective group ids.");
4349
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004350static PyObject *
4351posix_setregid (PyObject *self, PyObject *args)
4352{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004353 long rgid_arg, egid_arg;
4354 gid_t rgid, egid;
4355 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004356 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004357 rgid = rgid_arg;
4358 egid = egid_arg;
4359 if (egid != egid_arg || rgid != rgid_arg) {
4360 PyErr_SetString(PyExc_OverflowError, "group id too big");
4361 return NULL;
4362 }
4363 if (setregid(rgid, egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004364 return posix_error();
4365 } else {
4366 Py_INCREF(Py_None);
4367 return Py_None;
4368 }
4369}
4370#endif /* HAVE_SETREGID */
4371
Guido van Rossumb6775db1994-08-01 11:34:53 +00004372#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004373PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004374"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004375Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004376
Barry Warsaw53699e91996-12-10 23:23:01 +00004377static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004378posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004379{
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004380 long gid_arg;
4381 gid_t gid;
4382 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004383 return NULL;
Benjamin Petersonef3e4c22009-04-11 19:48:14 +00004384 gid = gid_arg;
4385 if (gid != gid_arg) {
4386 PyErr_SetString(PyExc_OverflowError, "group id too big");
4387 return NULL;
4388 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004389 if (setgid(gid) < 0)
4390 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004391 Py_INCREF(Py_None);
4392 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004393}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004394#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004395
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004396#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004397PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004398"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004399Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004400
4401static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004402posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004403{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004404 int i, len;
4405 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004406
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004407 if (!PySequence_Check(groups)) {
4408 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4409 return NULL;
4410 }
4411 len = PySequence_Size(groups);
4412 if (len > MAX_GROUPS) {
4413 PyErr_SetString(PyExc_ValueError, "too many groups");
4414 return NULL;
4415 }
4416 for(i = 0; i < len; i++) {
4417 PyObject *elem;
4418 elem = PySequence_GetItem(groups, i);
4419 if (!elem)
4420 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004421 if (!PyLong_Check(elem)) {
4422 PyErr_SetString(PyExc_TypeError,
4423 "groups must be integers");
4424 Py_DECREF(elem);
4425 return NULL;
4426 } else {
4427 unsigned long x = PyLong_AsUnsignedLong(elem);
4428 if (PyErr_Occurred()) {
4429 PyErr_SetString(PyExc_TypeError,
4430 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004431 Py_DECREF(elem);
4432 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004433 }
Georg Brandla13c2442005-11-22 19:30:31 +00004434 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004435 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004436 if (grouplist[i] != x) {
4437 PyErr_SetString(PyExc_TypeError,
4438 "group id too big");
4439 Py_DECREF(elem);
4440 return NULL;
4441 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004442 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004443 Py_DECREF(elem);
4444 }
4445
4446 if (setgroups(len, grouplist) < 0)
4447 return posix_error();
4448 Py_INCREF(Py_None);
4449 return Py_None;
4450}
4451#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004452
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004453#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4454static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004455wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004456{
4457 PyObject *result;
4458 static PyObject *struct_rusage;
4459
4460 if (pid == -1)
4461 return posix_error();
4462
4463 if (struct_rusage == NULL) {
Christian Heimes072c0f12008-01-03 23:01:04 +00004464 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004465 if (m == NULL)
4466 return NULL;
4467 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4468 Py_DECREF(m);
4469 if (struct_rusage == NULL)
4470 return NULL;
4471 }
4472
4473 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4474 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4475 if (!result)
4476 return NULL;
4477
4478#ifndef doubletime
4479#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4480#endif
4481
4482 PyStructSequence_SET_ITEM(result, 0,
4483 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4484 PyStructSequence_SET_ITEM(result, 1,
4485 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4486#define SET_INT(result, index, value)\
Christian Heimes217cfd12007-12-02 14:31:20 +00004487 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004488 SET_INT(result, 2, ru->ru_maxrss);
4489 SET_INT(result, 3, ru->ru_ixrss);
4490 SET_INT(result, 4, ru->ru_idrss);
4491 SET_INT(result, 5, ru->ru_isrss);
4492 SET_INT(result, 6, ru->ru_minflt);
4493 SET_INT(result, 7, ru->ru_majflt);
4494 SET_INT(result, 8, ru->ru_nswap);
4495 SET_INT(result, 9, ru->ru_inblock);
4496 SET_INT(result, 10, ru->ru_oublock);
4497 SET_INT(result, 11, ru->ru_msgsnd);
4498 SET_INT(result, 12, ru->ru_msgrcv);
4499 SET_INT(result, 13, ru->ru_nsignals);
4500 SET_INT(result, 14, ru->ru_nvcsw);
4501 SET_INT(result, 15, ru->ru_nivcsw);
4502#undef SET_INT
4503
4504 if (PyErr_Occurred()) {
4505 Py_DECREF(result);
4506 return NULL;
4507 }
4508
4509 return Py_BuildValue("iiN", pid, status, result);
4510}
4511#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4512
4513#ifdef HAVE_WAIT3
4514PyDoc_STRVAR(posix_wait3__doc__,
4515"wait3(options) -> (pid, status, rusage)\n\n\
4516Wait for completion of a child process.");
4517
4518static PyObject *
4519posix_wait3(PyObject *self, PyObject *args)
4520{
Christian Heimes292d3512008-02-03 16:51:08 +00004521 pid_t pid;
4522 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004523 struct rusage ru;
4524 WAIT_TYPE status;
4525 WAIT_STATUS_INT(status) = 0;
4526
4527 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4528 return NULL;
4529
4530 Py_BEGIN_ALLOW_THREADS
4531 pid = wait3(&status, options, &ru);
4532 Py_END_ALLOW_THREADS
4533
4534 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4535}
4536#endif /* HAVE_WAIT3 */
4537
4538#ifdef HAVE_WAIT4
4539PyDoc_STRVAR(posix_wait4__doc__,
4540"wait4(pid, options) -> (pid, status, rusage)\n\n\
4541Wait for completion of a given child process.");
4542
4543static PyObject *
4544posix_wait4(PyObject *self, PyObject *args)
4545{
Christian Heimes292d3512008-02-03 16:51:08 +00004546 pid_t pid;
4547 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004548 struct rusage ru;
4549 WAIT_TYPE status;
4550 WAIT_STATUS_INT(status) = 0;
4551
4552 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
4553 return NULL;
4554
4555 Py_BEGIN_ALLOW_THREADS
4556 pid = wait4(pid, &status, options, &ru);
4557 Py_END_ALLOW_THREADS
4558
4559 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4560}
4561#endif /* HAVE_WAIT4 */
4562
Guido van Rossumb6775db1994-08-01 11:34:53 +00004563#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004564PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004565"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004566Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004567
Barry Warsaw53699e91996-12-10 23:23:01 +00004568static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004569posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004570{
Christian Heimes292d3512008-02-03 16:51:08 +00004571 pid_t pid;
4572 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004573 WAIT_TYPE status;
4574 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004575
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004576 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004577 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004578 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004579 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004580 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004581 if (pid == -1)
4582 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004583
4584 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004585}
4586
Tim Petersab034fa2002-02-01 11:27:43 +00004587#elif defined(HAVE_CWAIT)
4588
4589/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004590PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004591"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004592"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004593
4594static PyObject *
4595posix_waitpid(PyObject *self, PyObject *args)
4596{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004597 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004598 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004599
4600 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4601 return NULL;
4602 Py_BEGIN_ALLOW_THREADS
4603 pid = _cwait(&status, pid, options);
4604 Py_END_ALLOW_THREADS
4605 if (pid == -1)
4606 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004607
4608 /* shift the status left a byte so this is more like the POSIX waitpid */
4609 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004610}
4611#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004612
Guido van Rossumad0ee831995-03-01 10:34:45 +00004613#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004614PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004615"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004616Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004617
Barry Warsaw53699e91996-12-10 23:23:01 +00004618static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004619posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004620{
Christian Heimes292d3512008-02-03 16:51:08 +00004621 pid_t pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004622 WAIT_TYPE status;
4623 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004624
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004625 Py_BEGIN_ALLOW_THREADS
4626 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004627 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004628 if (pid == -1)
4629 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004630
4631 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004632}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004633#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004634
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004635
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004636PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004637"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004638Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004639
Barry Warsaw53699e91996-12-10 23:23:01 +00004640static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004641posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004642{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004643#ifdef HAVE_LSTAT
Martin v. Löwis011e8422009-05-05 04:43:17 +00004644 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004645#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004646#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00004647 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004648#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00004649 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004650#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004651#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004652}
4653
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004654
Guido van Rossumb6775db1994-08-01 11:34:53 +00004655#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004656PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004657"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004658Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004659
Barry Warsaw53699e91996-12-10 23:23:01 +00004660static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004661posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004662{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004663 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004664 char buf[MAXPATHLEN];
Martin v. Löwis011e8422009-05-05 04:43:17 +00004665 PyObject *opath;
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004666 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004667 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004668 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004669
Martin v. Löwis011e8422009-05-05 04:43:17 +00004670 if (!PyArg_ParseTuple(args, "O&:readlink",
4671 PyUnicode_FSConverter, &opath))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004672 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004673 path = bytes2str(opath, 1);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004674 v = PySequence_GetItem(args, 0);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004675 if (v == NULL) {
Martin v. Löwis011e8422009-05-05 04:43:17 +00004676 release_bytes(opath);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004677 return NULL;
4678 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004679
4680 if (PyUnicode_Check(v)) {
4681 arg_is_unicode = 1;
4682 }
4683 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004684
Barry Warsaw53699e91996-12-10 23:23:01 +00004685 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004686 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004687 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004688 if (n < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004689 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004690
Martin v. Löwis011e8422009-05-05 04:43:17 +00004691 release_bytes(opath);
Christian Heimes72b710a2008-05-26 13:28:38 +00004692 v = PyBytes_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004693 if (arg_is_unicode) {
4694 PyObject *w;
4695
4696 w = PyUnicode_FromEncodedObject(v,
4697 Py_FileSystemDefaultEncoding,
Martin v. Löwis011e8422009-05-05 04:43:17 +00004698 "utf8b");
Thomas Wouters89f507f2006-12-13 04:49:30 +00004699 if (w != NULL) {
4700 Py_DECREF(v);
4701 v = w;
4702 }
4703 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004704 v = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004705 }
4706 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004707 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004708}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004709#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004710
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004711
Guido van Rossumb6775db1994-08-01 11:34:53 +00004712#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004713PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004714"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004715Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004716
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004718posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004719{
Martin v. Löwis011e8422009-05-05 04:43:17 +00004720 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004721}
4722#endif /* HAVE_SYMLINK */
4723
4724
4725#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00004726#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4727static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004728system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004729{
4730 ULONG value = 0;
4731
4732 Py_BEGIN_ALLOW_THREADS
4733 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4734 Py_END_ALLOW_THREADS
4735
4736 return value;
4737}
4738
4739static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004740posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004741{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004742 /* Currently Only Uptime is Provided -- Others Later */
4743 return Py_BuildValue("ddddd",
4744 (double)0 /* t.tms_utime / HZ */,
4745 (double)0 /* t.tms_stime / HZ */,
4746 (double)0 /* t.tms_cutime / HZ */,
4747 (double)0 /* t.tms_cstime / HZ */,
4748 (double)system_uptime() / 1000);
4749}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004750#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004751#define NEED_TICKS_PER_SECOND
4752static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00004753static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004754posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004755{
4756 struct tms t;
4757 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004758 errno = 0;
4759 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004760 if (c == (clock_t) -1)
4761 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004762 return Py_BuildValue("ddddd",
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004763 (double)t.tms_utime / ticks_per_second,
4764 (double)t.tms_stime / ticks_per_second,
4765 (double)t.tms_cutime / ticks_per_second,
4766 (double)t.tms_cstime / ticks_per_second,
4767 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004768}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004769#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004770#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004771
4772
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004773#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004774#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004775static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004776posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004777{
4778 FILETIME create, exit, kernel, user;
4779 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004780 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004781 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4782 /* The fields of a FILETIME structure are the hi and lo part
4783 of a 64-bit value expressed in 100 nanosecond units.
4784 1e7 is one second in such units; 1e-7 the inverse.
4785 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4786 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004787 return Py_BuildValue(
4788 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004789 (double)(user.dwHighDateTime*429.4967296 +
4790 user.dwLowDateTime*1e-7),
Christian Heimes68f5fbe2008-02-14 08:27:37 +00004791 (double)(kernel.dwHighDateTime*429.4967296 +
4792 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004793 (double)0,
4794 (double)0,
4795 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004796}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004797#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004798
4799#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004800PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004801"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004802Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004803#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004805
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004806#ifdef HAVE_GETSID
4807PyDoc_STRVAR(posix_getsid__doc__,
4808"getsid(pid) -> sid\n\n\
4809Call the system call getsid().");
4810
4811static PyObject *
4812posix_getsid(PyObject *self, PyObject *args)
4813{
Christian Heimes292d3512008-02-03 16:51:08 +00004814 pid_t pid;
4815 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004816 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4817 return NULL;
4818 sid = getsid(pid);
4819 if (sid < 0)
4820 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004821 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004822}
4823#endif /* HAVE_GETSID */
4824
4825
Guido van Rossumb6775db1994-08-01 11:34:53 +00004826#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004827PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004828"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004829Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004830
Barry Warsaw53699e91996-12-10 23:23:01 +00004831static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004832posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004833{
Guido van Rossum687dd131993-05-17 08:34:16 +00004834 if (setsid() < 0)
4835 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004836 Py_INCREF(Py_None);
4837 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004838}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004839#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004840
Guido van Rossumb6775db1994-08-01 11:34:53 +00004841#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004842PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004843"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004844Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004845
Barry Warsaw53699e91996-12-10 23:23:01 +00004846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004847posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004848{
Christian Heimes292d3512008-02-03 16:51:08 +00004849 pid_t pid;
4850 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004851 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004852 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004853 if (setpgid(pid, pgrp) < 0)
4854 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004855 Py_INCREF(Py_None);
4856 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004857}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004858#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004859
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004860
Guido van Rossumb6775db1994-08-01 11:34:53 +00004861#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004862PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004863"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004864Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004865
Barry Warsaw53699e91996-12-10 23:23:01 +00004866static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004867posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004868{
Christian Heimes15ebc882008-02-04 18:48:49 +00004869 int fd;
4870 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004871 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004872 return NULL;
4873 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004874 if (pgid < 0)
4875 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004876 return PyLong_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004877}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004878#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004879
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004880
Guido van Rossumb6775db1994-08-01 11:34:53 +00004881#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004882PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004883"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004884Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004885
Barry Warsaw53699e91996-12-10 23:23:01 +00004886static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004887posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004888{
4889 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004890 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004891 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004892 if (tcsetpgrp(fd, pgid) < 0)
4893 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004894 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004895 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004896}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004897#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004898
Guido van Rossum687dd131993-05-17 08:34:16 +00004899/* Functions acting on file descriptors */
4900
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004901PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004902"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004903Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004904
Barry Warsaw53699e91996-12-10 23:23:01 +00004905static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004906posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004907{
Martin v. Löwis011e8422009-05-05 04:43:17 +00004908 PyObject *ofile;
4909 char *file;
Guido van Rossum687dd131993-05-17 08:34:16 +00004910 int flag;
4911 int mode = 0777;
4912 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004913
4914#ifdef MS_WINDOWS
4915 if (unicode_file_names()) {
4916 PyUnicodeObject *po;
4917 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4918 Py_BEGIN_ALLOW_THREADS
4919 /* PyUnicode_AS_UNICODE OK without thread
4920 lock as it is a simple dereference. */
4921 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4922 Py_END_ALLOW_THREADS
4923 if (fd < 0)
4924 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004925 return PyLong_FromLong((long)fd);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004926 }
4927 /* Drop the argument parsing error as narrow strings
4928 are also valid. */
4929 PyErr_Clear();
4930 }
4931#endif
4932
Martin v. Löwis011e8422009-05-05 04:43:17 +00004933 if (!PyArg_ParseTuple(args, "O&i|i",
4934 PyUnicode_FSConverter, &ofile,
Mark Hammondef8b6542001-05-13 08:04:26 +00004935 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004936 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004937 file = bytes2str(ofile, 1);
Barry Warsaw53699e91996-12-10 23:23:01 +00004938 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004939 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004940 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004941 if (fd < 0)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004942 return posix_error_with_allocated_filename(ofile);
4943 release_bytes(ofile);
Christian Heimes217cfd12007-12-02 14:31:20 +00004944 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004945}
4946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004947
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004948PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004949"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004950Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004951
Barry Warsaw53699e91996-12-10 23:23:01 +00004952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004953posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004954{
4955 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004956 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004957 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004958 if (!_PyVerify_fd(fd))
4959 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004960 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004961 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004962 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004963 if (res < 0)
4964 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004965 Py_INCREF(Py_None);
4966 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004967}
4968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004969
Christian Heimesfdab48e2008-01-20 09:06:41 +00004970PyDoc_STRVAR(posix_closerange__doc__,
4971"closerange(fd_low, fd_high)\n\n\
4972Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
4973
4974static PyObject *
4975posix_closerange(PyObject *self, PyObject *args)
4976{
4977 int fd_from, fd_to, i;
4978 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
4979 return NULL;
4980 Py_BEGIN_ALLOW_THREADS
4981 for (i = fd_from; i < fd_to; i++)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004982 if (_PyVerify_fd(i))
4983 close(i);
Christian Heimesfdab48e2008-01-20 09:06:41 +00004984 Py_END_ALLOW_THREADS
4985 Py_RETURN_NONE;
4986}
4987
4988
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004989PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004990"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004991Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004992
Barry Warsaw53699e91996-12-10 23:23:01 +00004993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004994posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004995{
4996 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004997 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004998 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004999 if (!_PyVerify_fd(fd))
5000 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005001 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005002 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005003 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005004 if (fd < 0)
5005 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00005006 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005007}
5008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005009
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005010PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005011"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005012Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005013
Barry Warsaw53699e91996-12-10 23:23:01 +00005014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005015posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005016{
5017 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005018 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005019 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005020 if (!_PyVerify_fd_dup2(fd, fd2))
5021 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005022 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005023 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005024 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005025 if (res < 0)
5026 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005027 Py_INCREF(Py_None);
5028 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005029}
5030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005031
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005032PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005033"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005034Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005035
Barry Warsaw53699e91996-12-10 23:23:01 +00005036static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005037posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005038{
5039 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005040#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005041 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005042#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005043 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005044#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005045 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005046 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005047 return NULL;
5048#ifdef SEEK_SET
5049 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5050 switch (how) {
5051 case 0: how = SEEK_SET; break;
5052 case 1: how = SEEK_CUR; break;
5053 case 2: how = SEEK_END; break;
5054 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005055#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005056
5057#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005058 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005059#else
5060 pos = PyLong_Check(posobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00005061 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005062#endif
5063 if (PyErr_Occurred())
5064 return NULL;
5065
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005066 if (!_PyVerify_fd(fd))
5067 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005068 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005069#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005070 res = _lseeki64(fd, pos, how);
5071#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005072 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005073#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005074 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005075 if (res < 0)
5076 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005077
5078#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005079 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005080#else
5081 return PyLong_FromLongLong(res);
5082#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005083}
5084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005085
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005086PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005087"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005088Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005089
Barry Warsaw53699e91996-12-10 23:23:01 +00005090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005091posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005092{
Guido van Rossum572dbf82007-04-27 23:53:51 +00005093 int fd, size;
5094 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005095 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005096 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005097 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005098 if (size < 0) {
5099 errno = EINVAL;
5100 return posix_error();
5101 }
Christian Heimes72b710a2008-05-26 13:28:38 +00005102 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005103 if (buffer == NULL)
5104 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005105 if (!_PyVerify_fd(fd))
5106 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005107 Py_BEGIN_ALLOW_THREADS
Christian Heimes72b710a2008-05-26 13:28:38 +00005108 n = read(fd, PyBytes_AS_STRING(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005109 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005110 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005111 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005112 return posix_error();
5113 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005114 if (n != size)
Christian Heimes72b710a2008-05-26 13:28:38 +00005115 _PyBytes_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005116 return buffer;
5117}
5118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005120PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005121"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005122Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005123
Barry Warsaw53699e91996-12-10 23:23:01 +00005124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005125posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005126{
Martin v. Löwis423be952008-08-13 15:53:07 +00005127 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005128 int fd;
5129 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005130
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +00005131 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00005132 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005133 if (!_PyVerify_fd(fd))
5134 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005135 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00005136 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00005137 Py_END_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00005138 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00005139 if (size < 0)
5140 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00005141 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005142}
5143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005145PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005146"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005147Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005148
Barry Warsaw53699e91996-12-10 23:23:01 +00005149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005150posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005151{
5152 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005153 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005154 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005155 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005156 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005157#ifdef __VMS
5158 /* on OpenVMS we must ensure that all bytes are written to the file */
5159 fsync(fd);
5160#endif
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005161 if (!_PyVerify_fd(fd))
5162 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005163 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005164 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005165 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005166 if (res != 0) {
5167#ifdef MS_WINDOWS
5168 return win32_error("fstat", NULL);
5169#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005170 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005171#endif
5172 }
Tim Peters5aa91602002-01-30 05:46:57 +00005173
Martin v. Löwis14694662006-02-03 12:54:16 +00005174 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005175}
5176
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005177PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005178"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005179Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005180connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005181
5182static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005183posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005184{
5185 int fd;
5186 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5187 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005188 if (!_PyVerify_fd(fd))
5189 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00005190 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005191}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005192
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005193#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005194PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005195"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005196Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005197
Barry Warsaw53699e91996-12-10 23:23:01 +00005198static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005199posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005200{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005201#if defined(PYOS_OS2)
5202 HFILE read, write;
5203 APIRET rc;
5204
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005205 Py_BEGIN_ALLOW_THREADS
5206 rc = DosCreatePipe( &read, &write, 4096);
5207 Py_END_ALLOW_THREADS
5208 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005209 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005210
5211 return Py_BuildValue("(ii)", read, write);
5212#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005213#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005214 int fds[2];
5215 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005216 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005217 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005218 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005219 if (res != 0)
5220 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005221 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005222#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005223 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005224 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005225 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005226 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005227 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005228 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005229 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005230 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005231 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5232 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005233 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005234#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005235#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005236}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005237#endif /* HAVE_PIPE */
5238
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005239
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005240#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005241PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005242"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005243Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005244
Barry Warsaw53699e91996-12-10 23:23:01 +00005245static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005246posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005247{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005248 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005249 int mode = 0666;
5250 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005251 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005252 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005253 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005254 res = mkfifo(filename, mode);
5255 Py_END_ALLOW_THREADS
5256 if (res < 0)
5257 return posix_error();
5258 Py_INCREF(Py_None);
5259 return Py_None;
5260}
5261#endif
5262
5263
Neal Norwitz11690112002-07-30 01:08:28 +00005264#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005265PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005266"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005267Create a filesystem node (file, device special file or named pipe)\n\
5268named filename. mode specifies both the permissions to use and the\n\
5269type of node to be created, being combined (bitwise OR) with one of\n\
5270S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005271device defines the newly created device special file (probably using\n\
5272os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005273
5274
5275static PyObject *
5276posix_mknod(PyObject *self, PyObject *args)
5277{
5278 char *filename;
5279 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005280 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005281 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005282 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005283 return NULL;
5284 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005285 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005286 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005287 if (res < 0)
5288 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005289 Py_INCREF(Py_None);
5290 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005291}
5292#endif
5293
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005294#ifdef HAVE_DEVICE_MACROS
5295PyDoc_STRVAR(posix_major__doc__,
5296"major(device) -> major number\n\
5297Extracts a device major number from a raw device number.");
5298
5299static PyObject *
5300posix_major(PyObject *self, PyObject *args)
5301{
5302 int device;
5303 if (!PyArg_ParseTuple(args, "i:major", &device))
5304 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005305 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005306}
5307
5308PyDoc_STRVAR(posix_minor__doc__,
5309"minor(device) -> minor number\n\
5310Extracts a device minor number from a raw device number.");
5311
5312static PyObject *
5313posix_minor(PyObject *self, PyObject *args)
5314{
5315 int device;
5316 if (!PyArg_ParseTuple(args, "i:minor", &device))
5317 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005318 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005319}
5320
5321PyDoc_STRVAR(posix_makedev__doc__,
5322"makedev(major, minor) -> device number\n\
5323Composes a raw device number from the major and minor device numbers.");
5324
5325static PyObject *
5326posix_makedev(PyObject *self, PyObject *args)
5327{
5328 int major, minor;
5329 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5330 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005331 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005332}
5333#endif /* device macros */
5334
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005335
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005336#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005337PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005338"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005339Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005340
Barry Warsaw53699e91996-12-10 23:23:01 +00005341static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005342posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005343{
5344 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005345 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005346 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005347 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005348
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005349 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005350 return NULL;
5351
5352#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005353 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005354#else
5355 length = PyLong_Check(lenobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00005356 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005357#endif
5358 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005359 return NULL;
5360
Barry Warsaw53699e91996-12-10 23:23:01 +00005361 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005362 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005363 Py_END_ALLOW_THREADS
Benjamin Peterson9053d752009-01-19 17:53:36 +00005364 if (res < 0)
5365 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005366 Py_INCREF(Py_None);
5367 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005368}
5369#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005370
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005371#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005372PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005373"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005374Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005375
Fred Drake762e2061999-08-26 17:23:54 +00005376/* Save putenv() parameters as values here, so we can collect them when they
5377 * get re-set with another call for the same key. */
5378static PyObject *posix_putenv_garbage;
5379
Tim Peters5aa91602002-01-30 05:46:57 +00005380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005381posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005382{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005383#ifdef MS_WINDOWS
5384 wchar_t *s1, *s2;
5385 wchar_t *newenv;
5386#else
Martin v. Löwis011e8422009-05-05 04:43:17 +00005387 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005388 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005389 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005390#endif
Fred Drake762e2061999-08-26 17:23:54 +00005391 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005392 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005393
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005394#ifdef MS_WINDOWS
Martin v. Löwis011e8422009-05-05 04:43:17 +00005395 if (!PyArg_ParseTuple(args,
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005396 "uu:putenv",
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005397 &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005398 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005399#else
5400 if (!PyArg_ParseTuple(args,
5401 "O&O&:putenv",
5402 PyUnicode_FSConverter, &os1,
5403 PyUnicode_FSConverter, &os2))
5404 return NULL;
5405 s1 = bytes2str(os1, 1);
5406 s2 = bytes2str(os2, 1);
5407#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005408
5409#if defined(PYOS_OS2)
5410 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5411 APIRET rc;
5412
Guido van Rossumd48f2521997-12-05 22:19:34 +00005413 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5414 if (rc != NO_ERROR)
5415 return os2_error(rc);
5416
5417 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5418 APIRET rc;
5419
Guido van Rossumd48f2521997-12-05 22:19:34 +00005420 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5421 if (rc != NO_ERROR)
5422 return os2_error(rc);
5423 } else {
5424#endif
Fred Drake762e2061999-08-26 17:23:54 +00005425 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005426 /* len includes space for a trailing \0; the size arg to
Christian Heimes72b710a2008-05-26 13:28:38 +00005427 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005428#ifdef MS_WINDOWS
5429 len = wcslen(s1) + wcslen(s2) + 2;
5430 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5431#else
5432 len = strlen(s1) + strlen(s2) + 2;
Christian Heimes72b710a2008-05-26 13:28:38 +00005433 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005434#endif
Fred Drake762e2061999-08-26 17:23:54 +00005435 if (newstr == NULL)
5436 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005437#ifdef MS_WINDOWS
5438 newenv = PyUnicode_AsUnicode(newstr);
5439 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5440 if (_wputenv(newenv)) {
5441 Py_DECREF(newstr);
5442 posix_error();
5443 return NULL;
5444 }
5445#else
Christian Heimes72b710a2008-05-26 13:28:38 +00005446 newenv = PyBytes_AS_STRING(newstr);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005447 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5448 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005449 Py_DECREF(newstr);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005450 release_bytes(os1);
5451 release_bytes(os2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005452 posix_error();
5453 return NULL;
5454 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005455#endif
Fred Drake762e2061999-08-26 17:23:54 +00005456 /* Install the first arg and newstr in posix_putenv_garbage;
5457 * this will cause previous value to be collected. This has to
5458 * happen after the real putenv() call because the old value
5459 * was still accessible until then. */
5460 if (PyDict_SetItem(posix_putenv_garbage,
5461 PyTuple_GET_ITEM(args, 0), newstr)) {
5462 /* really not much we can do; just leak */
5463 PyErr_Clear();
5464 }
5465 else {
5466 Py_DECREF(newstr);
5467 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005468
5469#if defined(PYOS_OS2)
5470 }
5471#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00005472#ifndef MS_WINDOWS
5473 release_bytes(os1);
5474 release_bytes(os2);
5475#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005476 Py_INCREF(Py_None);
5477 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005478}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005479#endif /* putenv */
5480
Guido van Rossumc524d952001-10-19 01:31:59 +00005481#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005482PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005483"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005485
5486static PyObject *
5487posix_unsetenv(PyObject *self, PyObject *args)
5488{
5489 char *s1;
5490
5491 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5492 return NULL;
5493
5494 unsetenv(s1);
5495
5496 /* Remove the key from posix_putenv_garbage;
5497 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005498 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005499 * old value was still accessible until then.
5500 */
5501 if (PyDict_DelItem(posix_putenv_garbage,
5502 PyTuple_GET_ITEM(args, 0))) {
5503 /* really not much we can do; just leak */
5504 PyErr_Clear();
5505 }
5506
5507 Py_INCREF(Py_None);
5508 return Py_None;
5509}
5510#endif /* unsetenv */
5511
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005512PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005513"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005514Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005515
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005516static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005517posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005518{
5519 int code;
5520 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005521 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005522 return NULL;
5523 message = strerror(code);
5524 if (message == NULL) {
5525 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005526 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005527 return NULL;
5528 }
Neal Norwitz93c56822007-08-26 07:10:06 +00005529 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005530}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005531
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005532
Guido van Rossumc9641791998-08-04 15:26:23 +00005533#ifdef HAVE_SYS_WAIT_H
5534
Fred Drake106c1a02002-04-23 15:58:02 +00005535#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005536PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005537"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005538Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005539
5540static PyObject *
5541posix_WCOREDUMP(PyObject *self, PyObject *args)
5542{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005543 WAIT_TYPE status;
5544 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005545
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005546 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005547 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005548
5549 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005550}
5551#endif /* WCOREDUMP */
5552
5553#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005554PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005555"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005556Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005557job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005558
5559static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005560posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005561{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005562 WAIT_TYPE status;
5563 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005564
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005565 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005566 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005567
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005568 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005569}
5570#endif /* WIFCONTINUED */
5571
Guido van Rossumc9641791998-08-04 15:26:23 +00005572#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005573PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005574"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005575Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005576
5577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005578posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005579{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005580 WAIT_TYPE status;
5581 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005582
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005583 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005584 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005585
Fred Drake106c1a02002-04-23 15:58:02 +00005586 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005587}
5588#endif /* WIFSTOPPED */
5589
5590#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005591PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005592"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005593Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005594
5595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005596posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005597{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005598 WAIT_TYPE status;
5599 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005600
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005601 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005602 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005603
Fred Drake106c1a02002-04-23 15:58:02 +00005604 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005605}
5606#endif /* WIFSIGNALED */
5607
5608#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005609PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005610"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005611Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005612system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005613
5614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005615posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005616{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005617 WAIT_TYPE status;
5618 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005619
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005620 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005621 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005622
Fred Drake106c1a02002-04-23 15:58:02 +00005623 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005624}
5625#endif /* WIFEXITED */
5626
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005627#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005628PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005629"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005630Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005631
5632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005633posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005634{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005635 WAIT_TYPE status;
5636 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005637
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005638 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005639 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005640
Guido van Rossumc9641791998-08-04 15:26:23 +00005641 return Py_BuildValue("i", WEXITSTATUS(status));
5642}
5643#endif /* WEXITSTATUS */
5644
5645#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005646PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005647"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005648Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005649value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005650
5651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005652posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005653{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005654 WAIT_TYPE status;
5655 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005656
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005657 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005658 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005659
Guido van Rossumc9641791998-08-04 15:26:23 +00005660 return Py_BuildValue("i", WTERMSIG(status));
5661}
5662#endif /* WTERMSIG */
5663
5664#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005665PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005666"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667Return the signal that stopped the process that provided\n\
5668the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005669
5670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005671posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005672{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005673 WAIT_TYPE status;
5674 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005675
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005676 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005677 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005678
Guido van Rossumc9641791998-08-04 15:26:23 +00005679 return Py_BuildValue("i", WSTOPSIG(status));
5680}
5681#endif /* WSTOPSIG */
5682
5683#endif /* HAVE_SYS_WAIT_H */
5684
5685
Thomas Wouters477c8d52006-05-27 19:21:47 +00005686#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005687#ifdef _SCO_DS
5688/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5689 needed definitions in sys/statvfs.h */
5690#define _SVID3
5691#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005692#include <sys/statvfs.h>
5693
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005694static PyObject*
5695_pystatvfs_fromstructstatvfs(struct statvfs st) {
5696 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5697 if (v == NULL)
5698 return NULL;
5699
5700#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005701 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5702 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5703 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5704 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5705 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5706 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5707 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5708 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5709 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5710 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005711#else
Christian Heimes217cfd12007-12-02 14:31:20 +00005712 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5713 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005714 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005715 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005716 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005717 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005718 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005719 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005720 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005721 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005722 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005723 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005724 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005725 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Christian Heimes217cfd12007-12-02 14:31:20 +00005726 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5727 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005728#endif
5729
5730 return v;
5731}
5732
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005733PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005734"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005735Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005736
5737static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005738posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005739{
5740 int fd, res;
5741 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005742
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005743 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005744 return NULL;
5745 Py_BEGIN_ALLOW_THREADS
5746 res = fstatvfs(fd, &st);
5747 Py_END_ALLOW_THREADS
5748 if (res != 0)
5749 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005750
5751 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005752}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005753#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005754
5755
Thomas Wouters477c8d52006-05-27 19:21:47 +00005756#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005757#include <sys/statvfs.h>
5758
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005759PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005760"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005761Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005762
5763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005764posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005765{
5766 char *path;
5767 int res;
5768 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005769 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005770 return NULL;
5771 Py_BEGIN_ALLOW_THREADS
5772 res = statvfs(path, &st);
5773 Py_END_ALLOW_THREADS
5774 if (res != 0)
5775 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005776
5777 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005778}
5779#endif /* HAVE_STATVFS */
5780
Fred Drakec9680921999-12-13 16:37:25 +00005781/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5782 * It maps strings representing configuration variable names to
5783 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005784 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005785 * rarely-used constants. There are three separate tables that use
5786 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005787 *
5788 * This code is always included, even if none of the interfaces that
5789 * need it are included. The #if hackery needed to avoid it would be
5790 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005791 */
5792struct constdef {
5793 char *name;
5794 long value;
5795};
5796
Fred Drake12c6e2d1999-12-14 21:25:03 +00005797static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005798conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005799 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005800{
Christian Heimes217cfd12007-12-02 14:31:20 +00005801 if (PyLong_Check(arg)) {
5802 *valuep = PyLong_AS_LONG(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005803 return 1;
5804 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005805 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005806 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005807 size_t lo = 0;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005808 size_t mid;
Fred Drake699f3522000-06-29 21:12:41 +00005809 size_t hi = tablesize;
5810 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005811 const char *confname;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005812 if (!PyUnicode_Check(arg)) {
Guido van Rossumbce56a62007-05-10 18:04:33 +00005813 PyErr_SetString(PyExc_TypeError,
5814 "configuration names must be strings or integers");
5815 return 0;
5816 }
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00005817 confname = _PyUnicode_AsString(arg);
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005818 if (confname == NULL)
5819 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005820 while (lo < hi) {
5821 mid = (lo + hi) / 2;
5822 cmp = strcmp(confname, table[mid].name);
5823 if (cmp < 0)
5824 hi = mid;
5825 else if (cmp > 0)
5826 lo = mid + 1;
5827 else {
5828 *valuep = table[mid].value;
5829 return 1;
5830 }
5831 }
5832 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005833 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005834 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005835}
5836
5837
5838#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5839static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005840#ifdef _PC_ABI_AIO_XFER_MAX
5841 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5842#endif
5843#ifdef _PC_ABI_ASYNC_IO
5844 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5845#endif
Fred Drakec9680921999-12-13 16:37:25 +00005846#ifdef _PC_ASYNC_IO
5847 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5848#endif
5849#ifdef _PC_CHOWN_RESTRICTED
5850 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5851#endif
5852#ifdef _PC_FILESIZEBITS
5853 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5854#endif
5855#ifdef _PC_LAST
5856 {"PC_LAST", _PC_LAST},
5857#endif
5858#ifdef _PC_LINK_MAX
5859 {"PC_LINK_MAX", _PC_LINK_MAX},
5860#endif
5861#ifdef _PC_MAX_CANON
5862 {"PC_MAX_CANON", _PC_MAX_CANON},
5863#endif
5864#ifdef _PC_MAX_INPUT
5865 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5866#endif
5867#ifdef _PC_NAME_MAX
5868 {"PC_NAME_MAX", _PC_NAME_MAX},
5869#endif
5870#ifdef _PC_NO_TRUNC
5871 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5872#endif
5873#ifdef _PC_PATH_MAX
5874 {"PC_PATH_MAX", _PC_PATH_MAX},
5875#endif
5876#ifdef _PC_PIPE_BUF
5877 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5878#endif
5879#ifdef _PC_PRIO_IO
5880 {"PC_PRIO_IO", _PC_PRIO_IO},
5881#endif
5882#ifdef _PC_SOCK_MAXBUF
5883 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5884#endif
5885#ifdef _PC_SYNC_IO
5886 {"PC_SYNC_IO", _PC_SYNC_IO},
5887#endif
5888#ifdef _PC_VDISABLE
5889 {"PC_VDISABLE", _PC_VDISABLE},
5890#endif
5891};
5892
Fred Drakec9680921999-12-13 16:37:25 +00005893static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005894conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005895{
5896 return conv_confname(arg, valuep, posix_constants_pathconf,
5897 sizeof(posix_constants_pathconf)
5898 / sizeof(struct constdef));
5899}
5900#endif
5901
5902#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005903PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005904"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005905Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005906If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005907
5908static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005909posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005910{
5911 PyObject *result = NULL;
5912 int name, fd;
5913
Fred Drake12c6e2d1999-12-14 21:25:03 +00005914 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5915 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005916 long limit;
5917
5918 errno = 0;
5919 limit = fpathconf(fd, name);
5920 if (limit == -1 && errno != 0)
5921 posix_error();
5922 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005923 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005924 }
5925 return result;
5926}
5927#endif
5928
5929
5930#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005931PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005932"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005933Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005934If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005935
5936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005937posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005938{
5939 PyObject *result = NULL;
5940 int name;
5941 char *path;
5942
5943 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5944 conv_path_confname, &name)) {
5945 long limit;
5946
5947 errno = 0;
5948 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005949 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005950 if (errno == EINVAL)
5951 /* could be a path or name problem */
5952 posix_error();
5953 else
5954 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005955 }
Fred Drakec9680921999-12-13 16:37:25 +00005956 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005957 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005958 }
5959 return result;
5960}
5961#endif
5962
5963#ifdef HAVE_CONFSTR
5964static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005965#ifdef _CS_ARCHITECTURE
5966 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5967#endif
5968#ifdef _CS_HOSTNAME
5969 {"CS_HOSTNAME", _CS_HOSTNAME},
5970#endif
5971#ifdef _CS_HW_PROVIDER
5972 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5973#endif
5974#ifdef _CS_HW_SERIAL
5975 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5976#endif
5977#ifdef _CS_INITTAB_NAME
5978 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5979#endif
Fred Drakec9680921999-12-13 16:37:25 +00005980#ifdef _CS_LFS64_CFLAGS
5981 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5982#endif
5983#ifdef _CS_LFS64_LDFLAGS
5984 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5985#endif
5986#ifdef _CS_LFS64_LIBS
5987 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5988#endif
5989#ifdef _CS_LFS64_LINTFLAGS
5990 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5991#endif
5992#ifdef _CS_LFS_CFLAGS
5993 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5994#endif
5995#ifdef _CS_LFS_LDFLAGS
5996 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5997#endif
5998#ifdef _CS_LFS_LIBS
5999 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6000#endif
6001#ifdef _CS_LFS_LINTFLAGS
6002 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6003#endif
Fred Draked86ed291999-12-15 15:34:33 +00006004#ifdef _CS_MACHINE
6005 {"CS_MACHINE", _CS_MACHINE},
6006#endif
Fred Drakec9680921999-12-13 16:37:25 +00006007#ifdef _CS_PATH
6008 {"CS_PATH", _CS_PATH},
6009#endif
Fred Draked86ed291999-12-15 15:34:33 +00006010#ifdef _CS_RELEASE
6011 {"CS_RELEASE", _CS_RELEASE},
6012#endif
6013#ifdef _CS_SRPC_DOMAIN
6014 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6015#endif
6016#ifdef _CS_SYSNAME
6017 {"CS_SYSNAME", _CS_SYSNAME},
6018#endif
6019#ifdef _CS_VERSION
6020 {"CS_VERSION", _CS_VERSION},
6021#endif
Fred Drakec9680921999-12-13 16:37:25 +00006022#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6023 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6024#endif
6025#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6026 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6027#endif
6028#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6029 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6030#endif
6031#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6032 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6033#endif
6034#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6035 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6036#endif
6037#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6038 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6039#endif
6040#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6041 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6042#endif
6043#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6044 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6045#endif
6046#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6047 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6048#endif
6049#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6050 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6051#endif
6052#ifdef _CS_XBS5_LP64_OFF64_LIBS
6053 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6054#endif
6055#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6056 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6057#endif
6058#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6059 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6060#endif
6061#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6062 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6063#endif
6064#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6065 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6066#endif
6067#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6068 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6069#endif
Fred Draked86ed291999-12-15 15:34:33 +00006070#ifdef _MIPS_CS_AVAIL_PROCESSORS
6071 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6072#endif
6073#ifdef _MIPS_CS_BASE
6074 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6075#endif
6076#ifdef _MIPS_CS_HOSTID
6077 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6078#endif
6079#ifdef _MIPS_CS_HW_NAME
6080 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6081#endif
6082#ifdef _MIPS_CS_NUM_PROCESSORS
6083 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6084#endif
6085#ifdef _MIPS_CS_OSREL_MAJ
6086 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6087#endif
6088#ifdef _MIPS_CS_OSREL_MIN
6089 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6090#endif
6091#ifdef _MIPS_CS_OSREL_PATCH
6092 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6093#endif
6094#ifdef _MIPS_CS_OS_NAME
6095 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6096#endif
6097#ifdef _MIPS_CS_OS_PROVIDER
6098 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6099#endif
6100#ifdef _MIPS_CS_PROCESSORS
6101 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6102#endif
6103#ifdef _MIPS_CS_SERIAL
6104 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6105#endif
6106#ifdef _MIPS_CS_VENDOR
6107 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6108#endif
Fred Drakec9680921999-12-13 16:37:25 +00006109};
6110
6111static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006112conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006113{
6114 return conv_confname(arg, valuep, posix_constants_confstr,
6115 sizeof(posix_constants_confstr)
6116 / sizeof(struct constdef));
6117}
6118
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006119PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006120"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006122
6123static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006124posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006125{
6126 PyObject *result = NULL;
6127 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006128 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00006129
6130 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006131 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006132
Fred Drakec9680921999-12-13 16:37:25 +00006133 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006134 len = confstr(name, buffer, sizeof(buffer));
6135 if (len == 0) {
6136 if (errno) {
6137 posix_error();
6138 }
6139 else {
6140 result = Py_None;
6141 Py_INCREF(Py_None);
6142 }
Fred Drakec9680921999-12-13 16:37:25 +00006143 }
6144 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006145 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00006146 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006147 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00006148 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006149 }
6150 else
Neal Norwitz93c56822007-08-26 07:10:06 +00006151 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006152 }
6153 }
6154 return result;
6155}
6156#endif
6157
6158
6159#ifdef HAVE_SYSCONF
6160static struct constdef posix_constants_sysconf[] = {
6161#ifdef _SC_2_CHAR_TERM
6162 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6163#endif
6164#ifdef _SC_2_C_BIND
6165 {"SC_2_C_BIND", _SC_2_C_BIND},
6166#endif
6167#ifdef _SC_2_C_DEV
6168 {"SC_2_C_DEV", _SC_2_C_DEV},
6169#endif
6170#ifdef _SC_2_C_VERSION
6171 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6172#endif
6173#ifdef _SC_2_FORT_DEV
6174 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6175#endif
6176#ifdef _SC_2_FORT_RUN
6177 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6178#endif
6179#ifdef _SC_2_LOCALEDEF
6180 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6181#endif
6182#ifdef _SC_2_SW_DEV
6183 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6184#endif
6185#ifdef _SC_2_UPE
6186 {"SC_2_UPE", _SC_2_UPE},
6187#endif
6188#ifdef _SC_2_VERSION
6189 {"SC_2_VERSION", _SC_2_VERSION},
6190#endif
Fred Draked86ed291999-12-15 15:34:33 +00006191#ifdef _SC_ABI_ASYNCHRONOUS_IO
6192 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6193#endif
6194#ifdef _SC_ACL
6195 {"SC_ACL", _SC_ACL},
6196#endif
Fred Drakec9680921999-12-13 16:37:25 +00006197#ifdef _SC_AIO_LISTIO_MAX
6198 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6199#endif
Fred Drakec9680921999-12-13 16:37:25 +00006200#ifdef _SC_AIO_MAX
6201 {"SC_AIO_MAX", _SC_AIO_MAX},
6202#endif
6203#ifdef _SC_AIO_PRIO_DELTA_MAX
6204 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6205#endif
6206#ifdef _SC_ARG_MAX
6207 {"SC_ARG_MAX", _SC_ARG_MAX},
6208#endif
6209#ifdef _SC_ASYNCHRONOUS_IO
6210 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6211#endif
6212#ifdef _SC_ATEXIT_MAX
6213 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6214#endif
Fred Draked86ed291999-12-15 15:34:33 +00006215#ifdef _SC_AUDIT
6216 {"SC_AUDIT", _SC_AUDIT},
6217#endif
Fred Drakec9680921999-12-13 16:37:25 +00006218#ifdef _SC_AVPHYS_PAGES
6219 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6220#endif
6221#ifdef _SC_BC_BASE_MAX
6222 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6223#endif
6224#ifdef _SC_BC_DIM_MAX
6225 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6226#endif
6227#ifdef _SC_BC_SCALE_MAX
6228 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6229#endif
6230#ifdef _SC_BC_STRING_MAX
6231 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6232#endif
Fred Draked86ed291999-12-15 15:34:33 +00006233#ifdef _SC_CAP
6234 {"SC_CAP", _SC_CAP},
6235#endif
Fred Drakec9680921999-12-13 16:37:25 +00006236#ifdef _SC_CHARCLASS_NAME_MAX
6237 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6238#endif
6239#ifdef _SC_CHAR_BIT
6240 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6241#endif
6242#ifdef _SC_CHAR_MAX
6243 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6244#endif
6245#ifdef _SC_CHAR_MIN
6246 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6247#endif
6248#ifdef _SC_CHILD_MAX
6249 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6250#endif
6251#ifdef _SC_CLK_TCK
6252 {"SC_CLK_TCK", _SC_CLK_TCK},
6253#endif
6254#ifdef _SC_COHER_BLKSZ
6255 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6256#endif
6257#ifdef _SC_COLL_WEIGHTS_MAX
6258 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6259#endif
6260#ifdef _SC_DCACHE_ASSOC
6261 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6262#endif
6263#ifdef _SC_DCACHE_BLKSZ
6264 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6265#endif
6266#ifdef _SC_DCACHE_LINESZ
6267 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6268#endif
6269#ifdef _SC_DCACHE_SZ
6270 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6271#endif
6272#ifdef _SC_DCACHE_TBLKSZ
6273 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6274#endif
6275#ifdef _SC_DELAYTIMER_MAX
6276 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6277#endif
6278#ifdef _SC_EQUIV_CLASS_MAX
6279 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6280#endif
6281#ifdef _SC_EXPR_NEST_MAX
6282 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6283#endif
6284#ifdef _SC_FSYNC
6285 {"SC_FSYNC", _SC_FSYNC},
6286#endif
6287#ifdef _SC_GETGR_R_SIZE_MAX
6288 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6289#endif
6290#ifdef _SC_GETPW_R_SIZE_MAX
6291 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6292#endif
6293#ifdef _SC_ICACHE_ASSOC
6294 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6295#endif
6296#ifdef _SC_ICACHE_BLKSZ
6297 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6298#endif
6299#ifdef _SC_ICACHE_LINESZ
6300 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6301#endif
6302#ifdef _SC_ICACHE_SZ
6303 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6304#endif
Fred Draked86ed291999-12-15 15:34:33 +00006305#ifdef _SC_INF
6306 {"SC_INF", _SC_INF},
6307#endif
Fred Drakec9680921999-12-13 16:37:25 +00006308#ifdef _SC_INT_MAX
6309 {"SC_INT_MAX", _SC_INT_MAX},
6310#endif
6311#ifdef _SC_INT_MIN
6312 {"SC_INT_MIN", _SC_INT_MIN},
6313#endif
6314#ifdef _SC_IOV_MAX
6315 {"SC_IOV_MAX", _SC_IOV_MAX},
6316#endif
Fred Draked86ed291999-12-15 15:34:33 +00006317#ifdef _SC_IP_SECOPTS
6318 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6319#endif
Fred Drakec9680921999-12-13 16:37:25 +00006320#ifdef _SC_JOB_CONTROL
6321 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6322#endif
Fred Draked86ed291999-12-15 15:34:33 +00006323#ifdef _SC_KERN_POINTERS
6324 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6325#endif
6326#ifdef _SC_KERN_SIM
6327 {"SC_KERN_SIM", _SC_KERN_SIM},
6328#endif
Fred Drakec9680921999-12-13 16:37:25 +00006329#ifdef _SC_LINE_MAX
6330 {"SC_LINE_MAX", _SC_LINE_MAX},
6331#endif
6332#ifdef _SC_LOGIN_NAME_MAX
6333 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6334#endif
6335#ifdef _SC_LOGNAME_MAX
6336 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6337#endif
6338#ifdef _SC_LONG_BIT
6339 {"SC_LONG_BIT", _SC_LONG_BIT},
6340#endif
Fred Draked86ed291999-12-15 15:34:33 +00006341#ifdef _SC_MAC
6342 {"SC_MAC", _SC_MAC},
6343#endif
Fred Drakec9680921999-12-13 16:37:25 +00006344#ifdef _SC_MAPPED_FILES
6345 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6346#endif
6347#ifdef _SC_MAXPID
6348 {"SC_MAXPID", _SC_MAXPID},
6349#endif
6350#ifdef _SC_MB_LEN_MAX
6351 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6352#endif
6353#ifdef _SC_MEMLOCK
6354 {"SC_MEMLOCK", _SC_MEMLOCK},
6355#endif
6356#ifdef _SC_MEMLOCK_RANGE
6357 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6358#endif
6359#ifdef _SC_MEMORY_PROTECTION
6360 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6361#endif
6362#ifdef _SC_MESSAGE_PASSING
6363 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6364#endif
Fred Draked86ed291999-12-15 15:34:33 +00006365#ifdef _SC_MMAP_FIXED_ALIGNMENT
6366 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6367#endif
Fred Drakec9680921999-12-13 16:37:25 +00006368#ifdef _SC_MQ_OPEN_MAX
6369 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6370#endif
6371#ifdef _SC_MQ_PRIO_MAX
6372 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6373#endif
Fred Draked86ed291999-12-15 15:34:33 +00006374#ifdef _SC_NACLS_MAX
6375 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6376#endif
Fred Drakec9680921999-12-13 16:37:25 +00006377#ifdef _SC_NGROUPS_MAX
6378 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6379#endif
6380#ifdef _SC_NL_ARGMAX
6381 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6382#endif
6383#ifdef _SC_NL_LANGMAX
6384 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6385#endif
6386#ifdef _SC_NL_MSGMAX
6387 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6388#endif
6389#ifdef _SC_NL_NMAX
6390 {"SC_NL_NMAX", _SC_NL_NMAX},
6391#endif
6392#ifdef _SC_NL_SETMAX
6393 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6394#endif
6395#ifdef _SC_NL_TEXTMAX
6396 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6397#endif
6398#ifdef _SC_NPROCESSORS_CONF
6399 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6400#endif
6401#ifdef _SC_NPROCESSORS_ONLN
6402 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6403#endif
Fred Draked86ed291999-12-15 15:34:33 +00006404#ifdef _SC_NPROC_CONF
6405 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6406#endif
6407#ifdef _SC_NPROC_ONLN
6408 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6409#endif
Fred Drakec9680921999-12-13 16:37:25 +00006410#ifdef _SC_NZERO
6411 {"SC_NZERO", _SC_NZERO},
6412#endif
6413#ifdef _SC_OPEN_MAX
6414 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6415#endif
6416#ifdef _SC_PAGESIZE
6417 {"SC_PAGESIZE", _SC_PAGESIZE},
6418#endif
6419#ifdef _SC_PAGE_SIZE
6420 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6421#endif
6422#ifdef _SC_PASS_MAX
6423 {"SC_PASS_MAX", _SC_PASS_MAX},
6424#endif
6425#ifdef _SC_PHYS_PAGES
6426 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6427#endif
6428#ifdef _SC_PII
6429 {"SC_PII", _SC_PII},
6430#endif
6431#ifdef _SC_PII_INTERNET
6432 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6433#endif
6434#ifdef _SC_PII_INTERNET_DGRAM
6435 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6436#endif
6437#ifdef _SC_PII_INTERNET_STREAM
6438 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6439#endif
6440#ifdef _SC_PII_OSI
6441 {"SC_PII_OSI", _SC_PII_OSI},
6442#endif
6443#ifdef _SC_PII_OSI_CLTS
6444 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6445#endif
6446#ifdef _SC_PII_OSI_COTS
6447 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6448#endif
6449#ifdef _SC_PII_OSI_M
6450 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6451#endif
6452#ifdef _SC_PII_SOCKET
6453 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6454#endif
6455#ifdef _SC_PII_XTI
6456 {"SC_PII_XTI", _SC_PII_XTI},
6457#endif
6458#ifdef _SC_POLL
6459 {"SC_POLL", _SC_POLL},
6460#endif
6461#ifdef _SC_PRIORITIZED_IO
6462 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6463#endif
6464#ifdef _SC_PRIORITY_SCHEDULING
6465 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6466#endif
6467#ifdef _SC_REALTIME_SIGNALS
6468 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6469#endif
6470#ifdef _SC_RE_DUP_MAX
6471 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6472#endif
6473#ifdef _SC_RTSIG_MAX
6474 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6475#endif
6476#ifdef _SC_SAVED_IDS
6477 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6478#endif
6479#ifdef _SC_SCHAR_MAX
6480 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6481#endif
6482#ifdef _SC_SCHAR_MIN
6483 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6484#endif
6485#ifdef _SC_SELECT
6486 {"SC_SELECT", _SC_SELECT},
6487#endif
6488#ifdef _SC_SEMAPHORES
6489 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6490#endif
6491#ifdef _SC_SEM_NSEMS_MAX
6492 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6493#endif
6494#ifdef _SC_SEM_VALUE_MAX
6495 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6496#endif
6497#ifdef _SC_SHARED_MEMORY_OBJECTS
6498 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6499#endif
6500#ifdef _SC_SHRT_MAX
6501 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6502#endif
6503#ifdef _SC_SHRT_MIN
6504 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6505#endif
6506#ifdef _SC_SIGQUEUE_MAX
6507 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6508#endif
6509#ifdef _SC_SIGRT_MAX
6510 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6511#endif
6512#ifdef _SC_SIGRT_MIN
6513 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6514#endif
Fred Draked86ed291999-12-15 15:34:33 +00006515#ifdef _SC_SOFTPOWER
6516 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6517#endif
Fred Drakec9680921999-12-13 16:37:25 +00006518#ifdef _SC_SPLIT_CACHE
6519 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6520#endif
6521#ifdef _SC_SSIZE_MAX
6522 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6523#endif
6524#ifdef _SC_STACK_PROT
6525 {"SC_STACK_PROT", _SC_STACK_PROT},
6526#endif
6527#ifdef _SC_STREAM_MAX
6528 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6529#endif
6530#ifdef _SC_SYNCHRONIZED_IO
6531 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6532#endif
6533#ifdef _SC_THREADS
6534 {"SC_THREADS", _SC_THREADS},
6535#endif
6536#ifdef _SC_THREAD_ATTR_STACKADDR
6537 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6538#endif
6539#ifdef _SC_THREAD_ATTR_STACKSIZE
6540 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6541#endif
6542#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6543 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6544#endif
6545#ifdef _SC_THREAD_KEYS_MAX
6546 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6547#endif
6548#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6549 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6550#endif
6551#ifdef _SC_THREAD_PRIO_INHERIT
6552 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6553#endif
6554#ifdef _SC_THREAD_PRIO_PROTECT
6555 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6556#endif
6557#ifdef _SC_THREAD_PROCESS_SHARED
6558 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6559#endif
6560#ifdef _SC_THREAD_SAFE_FUNCTIONS
6561 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6562#endif
6563#ifdef _SC_THREAD_STACK_MIN
6564 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6565#endif
6566#ifdef _SC_THREAD_THREADS_MAX
6567 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6568#endif
6569#ifdef _SC_TIMERS
6570 {"SC_TIMERS", _SC_TIMERS},
6571#endif
6572#ifdef _SC_TIMER_MAX
6573 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6574#endif
6575#ifdef _SC_TTY_NAME_MAX
6576 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6577#endif
6578#ifdef _SC_TZNAME_MAX
6579 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6580#endif
6581#ifdef _SC_T_IOV_MAX
6582 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6583#endif
6584#ifdef _SC_UCHAR_MAX
6585 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6586#endif
6587#ifdef _SC_UINT_MAX
6588 {"SC_UINT_MAX", _SC_UINT_MAX},
6589#endif
6590#ifdef _SC_UIO_MAXIOV
6591 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6592#endif
6593#ifdef _SC_ULONG_MAX
6594 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6595#endif
6596#ifdef _SC_USHRT_MAX
6597 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6598#endif
6599#ifdef _SC_VERSION
6600 {"SC_VERSION", _SC_VERSION},
6601#endif
6602#ifdef _SC_WORD_BIT
6603 {"SC_WORD_BIT", _SC_WORD_BIT},
6604#endif
6605#ifdef _SC_XBS5_ILP32_OFF32
6606 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6607#endif
6608#ifdef _SC_XBS5_ILP32_OFFBIG
6609 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6610#endif
6611#ifdef _SC_XBS5_LP64_OFF64
6612 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6613#endif
6614#ifdef _SC_XBS5_LPBIG_OFFBIG
6615 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6616#endif
6617#ifdef _SC_XOPEN_CRYPT
6618 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6619#endif
6620#ifdef _SC_XOPEN_ENH_I18N
6621 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6622#endif
6623#ifdef _SC_XOPEN_LEGACY
6624 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6625#endif
6626#ifdef _SC_XOPEN_REALTIME
6627 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6628#endif
6629#ifdef _SC_XOPEN_REALTIME_THREADS
6630 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6631#endif
6632#ifdef _SC_XOPEN_SHM
6633 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6634#endif
6635#ifdef _SC_XOPEN_UNIX
6636 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6637#endif
6638#ifdef _SC_XOPEN_VERSION
6639 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6640#endif
6641#ifdef _SC_XOPEN_XCU_VERSION
6642 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6643#endif
6644#ifdef _SC_XOPEN_XPG2
6645 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6646#endif
6647#ifdef _SC_XOPEN_XPG3
6648 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6649#endif
6650#ifdef _SC_XOPEN_XPG4
6651 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6652#endif
6653};
6654
6655static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006656conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006657{
6658 return conv_confname(arg, valuep, posix_constants_sysconf,
6659 sizeof(posix_constants_sysconf)
6660 / sizeof(struct constdef));
6661}
6662
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006663PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006664"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006665Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006666
6667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006668posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006669{
6670 PyObject *result = NULL;
6671 int name;
6672
6673 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6674 int value;
6675
6676 errno = 0;
6677 value = sysconf(name);
6678 if (value == -1 && errno != 0)
6679 posix_error();
6680 else
Christian Heimes217cfd12007-12-02 14:31:20 +00006681 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00006682 }
6683 return result;
6684}
6685#endif
6686
6687
Fred Drakebec628d1999-12-15 18:31:10 +00006688/* This code is used to ensure that the tables of configuration value names
6689 * are in sorted order as required by conv_confname(), and also to build the
6690 * the exported dictionaries that are used to publish information about the
6691 * names available on the host platform.
6692 *
6693 * Sorting the table at runtime ensures that the table is properly ordered
6694 * when used, even for platforms we're not able to test on. It also makes
6695 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006696 */
Fred Drakebec628d1999-12-15 18:31:10 +00006697
6698static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006699cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006700{
6701 const struct constdef *c1 =
6702 (const struct constdef *) v1;
6703 const struct constdef *c2 =
6704 (const struct constdef *) v2;
6705
6706 return strcmp(c1->name, c2->name);
6707}
6708
6709static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006710setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006711 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006712{
Fred Drakebec628d1999-12-15 18:31:10 +00006713 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006714 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006715
6716 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6717 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006718 if (d == NULL)
6719 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006720
Barry Warsaw3155db32000-04-13 15:20:40 +00006721 for (i=0; i < tablesize; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00006722 PyObject *o = PyLong_FromLong(table[i].value);
Barry Warsaw3155db32000-04-13 15:20:40 +00006723 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6724 Py_XDECREF(o);
6725 Py_DECREF(d);
6726 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006727 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006728 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006729 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006730 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006731}
6732
Fred Drakebec628d1999-12-15 18:31:10 +00006733/* Return -1 on failure, 0 on success. */
6734static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006735setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006736{
6737#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006738 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006739 sizeof(posix_constants_pathconf)
6740 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006741 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006742 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006743#endif
6744#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006745 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006746 sizeof(posix_constants_confstr)
6747 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006748 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006749 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006750#endif
6751#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006752 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006753 sizeof(posix_constants_sysconf)
6754 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006755 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006756 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006757#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006758 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006759}
Fred Draked86ed291999-12-15 15:34:33 +00006760
6761
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006762PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006763"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006764Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006765in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006766
6767static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006768posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006769{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006770 abort();
6771 /*NOTREACHED*/
6772 Py_FatalError("abort() called from Python code didn't abort!");
6773 return NULL;
6774}
Fred Drakebec628d1999-12-15 18:31:10 +00006775
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006776#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006777PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006778"startfile(filepath [, operation]) - Start a file with its associated\n\
6779application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006780\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006781When \"operation\" is not specified or \"open\", this acts like\n\
6782double-clicking the file in Explorer, or giving the file name as an\n\
6783argument to the DOS \"start\" command: the file is opened with whatever\n\
6784application (if any) its extension is associated.\n\
6785When another \"operation\" is given, it specifies what should be done with\n\
6786the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006787\n\
6788startfile returns as soon as the associated application is launched.\n\
6789There is no option to wait for the application to close, and no way\n\
6790to retrieve the application's exit status.\n\
6791\n\
6792The filepath is relative to the current directory. If you want to use\n\
6793an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006794the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006795
6796static PyObject *
6797win32_startfile(PyObject *self, PyObject *args)
6798{
Martin v. Löwis011e8422009-05-05 04:43:17 +00006799 PyObject *ofilepath;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006800 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006801 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006802 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006803#ifdef Py_WIN_WIDE_FILENAMES
6804 if (unicode_file_names()) {
6805 PyObject *unipath, *woperation = NULL;
6806 if (!PyArg_ParseTuple(args, "U|s:startfile",
6807 &unipath, &operation)) {
6808 PyErr_Clear();
6809 goto normal;
6810 }
6811
6812
6813 if (operation) {
6814 woperation = PyUnicode_DecodeASCII(operation,
6815 strlen(operation), NULL);
6816 if (!woperation) {
6817 PyErr_Clear();
6818 operation = NULL;
6819 goto normal;
6820 }
6821 }
6822
6823 Py_BEGIN_ALLOW_THREADS
6824 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6825 PyUnicode_AS_UNICODE(unipath),
6826 NULL, NULL, SW_SHOWNORMAL);
6827 Py_END_ALLOW_THREADS
6828
6829 Py_XDECREF(woperation);
6830 if (rc <= (HINSTANCE)32) {
6831 PyObject *errval = win32_error_unicode("startfile",
6832 PyUnicode_AS_UNICODE(unipath));
6833 return errval;
6834 }
6835 Py_INCREF(Py_None);
6836 return Py_None;
6837 }
6838#endif
6839
6840normal:
Martin v. Löwis011e8422009-05-05 04:43:17 +00006841 if (!PyArg_ParseTuple(args, "O&|s:startfile",
6842 PyUnicode_FSConverter, &ofilepath,
Georg Brandlf4f44152006-02-18 22:29:33 +00006843 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006844 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00006845 filepath = bytes2str(ofilepath, 1);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006846 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006847 rc = ShellExecute((HWND)0, operation, filepath,
6848 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006849 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006850 if (rc <= (HINSTANCE)32) {
6851 PyObject *errval = win32_error("startfile", filepath);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006852 release_bytes(ofilepath);
Georg Brandle9f8ec92005-09-25 06:16:40 +00006853 return errval;
6854 }
Martin v. Löwis011e8422009-05-05 04:43:17 +00006855 release_bytes(ofilepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006856 Py_INCREF(Py_None);
6857 return Py_None;
6858}
6859#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006860
Martin v. Löwis438b5342002-12-27 10:16:42 +00006861#ifdef HAVE_GETLOADAVG
6862PyDoc_STRVAR(posix_getloadavg__doc__,
6863"getloadavg() -> (float, float, float)\n\n\
6864Return the number of processes in the system run queue averaged over\n\
6865the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6866was unobtainable");
6867
6868static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006869posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006870{
6871 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006872 if (getloadavg(loadavg, 3)!=3) {
6873 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6874 return NULL;
6875 } else
6876 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6877}
6878#endif
6879
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006880#ifdef MS_WINDOWS
6881
6882PyDoc_STRVAR(win32_urandom__doc__,
6883"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006884Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006885
6886typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6887 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6888 DWORD dwFlags );
6889typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6890 BYTE *pbBuffer );
6891
6892static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006893/* This handle is never explicitly released. Instead, the operating
6894 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006895static HCRYPTPROV hCryptProv = 0;
6896
Tim Peters4ad82172004-08-30 17:02:04 +00006897static PyObject*
6898win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006899{
Tim Petersd3115382004-08-30 17:36:46 +00006900 int howMany;
6901 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006902
Tim Peters4ad82172004-08-30 17:02:04 +00006903 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006904 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006905 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006906 if (howMany < 0)
6907 return PyErr_Format(PyExc_ValueError,
6908 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006909
Tim Peters4ad82172004-08-30 17:02:04 +00006910 if (hCryptProv == 0) {
6911 HINSTANCE hAdvAPI32 = NULL;
6912 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006913
Tim Peters4ad82172004-08-30 17:02:04 +00006914 /* Obtain handle to the DLL containing CryptoAPI
6915 This should not fail */
6916 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6917 if(hAdvAPI32 == NULL)
6918 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006919
Tim Peters4ad82172004-08-30 17:02:04 +00006920 /* Obtain pointers to the CryptoAPI functions
6921 This will fail on some early versions of Win95 */
6922 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6923 hAdvAPI32,
6924 "CryptAcquireContextA");
6925 if (pCryptAcquireContext == NULL)
6926 return PyErr_Format(PyExc_NotImplementedError,
6927 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006928
Tim Peters4ad82172004-08-30 17:02:04 +00006929 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6930 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006931 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006932 return PyErr_Format(PyExc_NotImplementedError,
6933 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006934
Tim Peters4ad82172004-08-30 17:02:04 +00006935 /* Acquire context */
6936 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6937 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6938 return win32_error("CryptAcquireContext", NULL);
6939 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006940
Tim Peters4ad82172004-08-30 17:02:04 +00006941 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006942 result = PyBytes_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00006943 if (result != NULL) {
6944 /* Get random data */
Amaury Forgeot d'Arca05ada32008-07-21 21:13:14 +00006945 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00006946 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006947 PyBytes_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00006948 Py_DECREF(result);
6949 return win32_error("CryptGenRandom", NULL);
6950 }
Tim Peters4ad82172004-08-30 17:02:04 +00006951 }
Tim Petersd3115382004-08-30 17:36:46 +00006952 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006953}
6954#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006955
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006956PyDoc_STRVAR(device_encoding__doc__,
6957"device_encoding(fd) -> str\n\n\
6958Return a string describing the encoding of the device\n\
6959if the output is a terminal; else return None.");
6960
6961static PyObject *
6962device_encoding(PyObject *self, PyObject *args)
6963{
6964 int fd;
6965 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6966 return NULL;
Kristján Valur Jónsson649170b2009-03-24 14:15:49 +00006967 if (!_PyVerify_fd(fd) || !isatty(fd)) {
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006968 Py_INCREF(Py_None);
6969 return Py_None;
6970 }
6971#if defined(MS_WINDOWS) || defined(MS_WIN64)
6972 if (fd == 0) {
6973 char buf[100];
6974 sprintf(buf, "cp%d", GetConsoleCP());
6975 return PyUnicode_FromString(buf);
6976 }
6977 if (fd == 1 || fd == 2) {
6978 char buf[100];
6979 sprintf(buf, "cp%d", GetConsoleOutputCP());
6980 return PyUnicode_FromString(buf);
6981 }
6982#elif defined(CODESET)
6983 {
6984 char *codeset = nl_langinfo(CODESET);
Mark Dickinsonda2706b2008-12-11 18:03:03 +00006985 if (codeset != NULL && codeset[0] != 0)
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006986 return PyUnicode_FromString(codeset);
6987 }
6988#endif
6989 Py_INCREF(Py_None);
6990 return Py_None;
6991}
6992
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006993#ifdef __VMS
6994/* Use openssl random routine */
6995#include <openssl/rand.h>
6996PyDoc_STRVAR(vms_urandom__doc__,
6997"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006998Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006999
7000static PyObject*
7001vms_urandom(PyObject *self, PyObject *args)
7002{
7003 int howMany;
7004 PyObject* result;
7005
7006 /* Read arguments */
7007 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7008 return NULL;
7009 if (howMany < 0)
7010 return PyErr_Format(PyExc_ValueError,
7011 "negative argument not allowed");
7012
7013 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00007014 result = PyBytes_FromStringAndSize(NULL, howMany);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007015 if (result != NULL) {
7016 /* Get random data */
7017 if (RAND_pseudo_bytes((unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00007018 PyBytes_AS_STRING(result),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007019 howMany) < 0) {
7020 Py_DECREF(result);
7021 return PyErr_Format(PyExc_ValueError,
7022 "RAND_pseudo_bytes");
7023 }
7024 }
7025 return result;
7026}
7027#endif
7028
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007029static PyMethodDef posix_methods[] = {
7030 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7031#ifdef HAVE_TTYNAME
7032 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7033#endif
7034 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007035#ifdef HAVE_CHFLAGS
7036 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
7037#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007038 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007039#ifdef HAVE_FCHMOD
7040 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
7041#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007042#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007043 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007044#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007045#ifdef HAVE_LCHMOD
7046 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
7047#endif /* HAVE_LCHMOD */
7048#ifdef HAVE_FCHOWN
7049 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
7050#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007051#ifdef HAVE_LCHFLAGS
7052 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
7053#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007054#ifdef HAVE_LCHOWN
7055 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7056#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007057#ifdef HAVE_CHROOT
7058 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7059#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007060#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007061 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007062#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007063#ifdef HAVE_GETCWD
Guido van Rossumf0af3e32008-10-02 18:55:37 +00007064 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7065 METH_NOARGS, posix_getcwd__doc__},
7066 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7067 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007068#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007069#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007070 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007071#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007072 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7073 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7074 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007075#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007076 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007077#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007078#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007079 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007080#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007081 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7082 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7083 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007084 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007085#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007086 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007087#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007088#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007089 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007090#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007091 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007092#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007093 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007094#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007095 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7096 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7097 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007098#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007099 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007100#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007101 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007102#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007103 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7104 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007105#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007106#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007107 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7108 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007109#if defined(PYOS_OS2)
7110 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7111 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7112#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007113#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007114#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007115 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007116#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007117#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007118 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007119#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007120#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007121 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007122#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007123#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007124 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007125#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007126#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007127 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007128#endif /* HAVE_GETEGID */
7129#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007130 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007131#endif /* HAVE_GETEUID */
7132#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007133 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007134#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007135#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007136 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007137#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007138 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007139#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007140 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007141#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007142#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007143 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007144#endif /* HAVE_GETPPID */
7145#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007146 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007147#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007148#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007149 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007150#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007151#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007152 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007153#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007154#ifdef HAVE_KILLPG
7155 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7156#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007157#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007158 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007159#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007160#ifdef MS_WINDOWS
7161 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7162#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007163#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007164 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007165#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007166#ifdef HAVE_SETEUID
7167 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7168#endif /* HAVE_SETEUID */
7169#ifdef HAVE_SETEGID
7170 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7171#endif /* HAVE_SETEGID */
7172#ifdef HAVE_SETREUID
7173 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7174#endif /* HAVE_SETREUID */
7175#ifdef HAVE_SETREGID
7176 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7177#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007178#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007179 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007180#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007181#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00007182 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007183#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007184#ifdef HAVE_GETPGID
7185 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7186#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007187#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007188 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007189#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007190#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007191 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007192#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007193#ifdef HAVE_WAIT3
7194 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7195#endif /* HAVE_WAIT3 */
7196#ifdef HAVE_WAIT4
7197 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7198#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007199#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007200 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007201#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007202#ifdef HAVE_GETSID
7203 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7204#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007205#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007206 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007207#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007208#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007209 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007210#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007211#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007212 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007213#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007214#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007215 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007216#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007217 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7218 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Christian Heimesfdab48e2008-01-20 09:06:41 +00007219 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007220 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007221 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7222 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7223 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7224 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7225 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7226 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007227 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007228#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007229 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007230#endif
7231#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007232 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007233#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007234#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007235 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7236#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007237#ifdef HAVE_DEVICE_MACROS
7238 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7239 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7240 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7241#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007242#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007243 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007244#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007245#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007246 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007247#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007248#ifdef HAVE_UNSETENV
7249 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7250#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007251 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007252#ifdef HAVE_FCHDIR
7253 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7254#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007255#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007256 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007257#endif
7258#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007259 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007260#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007261#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007262#ifdef WCOREDUMP
7263 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7264#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007265#ifdef WIFCONTINUED
7266 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7267#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007268#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007269 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007270#endif /* WIFSTOPPED */
7271#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007272 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007273#endif /* WIFSIGNALED */
7274#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007275 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007276#endif /* WIFEXITED */
7277#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007278 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007279#endif /* WEXITSTATUS */
7280#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007281 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007282#endif /* WTERMSIG */
7283#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007284 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007285#endif /* WSTOPSIG */
7286#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007287#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007288 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007289#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007290#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007291 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007292#endif
Fred Drakec9680921999-12-13 16:37:25 +00007293#ifdef HAVE_CONFSTR
7294 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7295#endif
7296#ifdef HAVE_SYSCONF
7297 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7298#endif
7299#ifdef HAVE_FPATHCONF
7300 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7301#endif
7302#ifdef HAVE_PATHCONF
7303 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7304#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007305 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007306#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007307 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7308#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007309#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007310 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007311#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007312 #ifdef MS_WINDOWS
7313 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7314 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007315 #ifdef __VMS
7316 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
7317 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007318 {NULL, NULL} /* Sentinel */
7319};
7320
7321
Barry Warsaw4a342091996-12-19 23:50:02 +00007322static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007323ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007324{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007325 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007326}
7327
Guido van Rossumd48f2521997-12-05 22:19:34 +00007328#if defined(PYOS_OS2)
7329/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007330static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007331{
7332 APIRET rc;
7333 ULONG values[QSV_MAX+1];
7334 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007335 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007336
7337 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007338 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007339 Py_END_ALLOW_THREADS
7340
7341 if (rc != NO_ERROR) {
7342 os2_error(rc);
7343 return -1;
7344 }
7345
Fred Drake4d1e64b2002-04-15 19:40:07 +00007346 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7347 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7348 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7349 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7350 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7351 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7352 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007353
7354 switch (values[QSV_VERSION_MINOR]) {
7355 case 0: ver = "2.00"; break;
7356 case 10: ver = "2.10"; break;
7357 case 11: ver = "2.11"; break;
7358 case 30: ver = "3.00"; break;
7359 case 40: ver = "4.00"; break;
7360 case 50: ver = "5.00"; break;
7361 default:
Tim Peters885d4572001-11-28 20:27:42 +00007362 PyOS_snprintf(tmp, sizeof(tmp),
7363 "%d-%d", values[QSV_VERSION_MAJOR],
7364 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007365 ver = &tmp[0];
7366 }
7367
7368 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007369 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007370 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007371
7372 /* Add Indicator of Which Drive was Used to Boot the System */
7373 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7374 tmp[1] = ':';
7375 tmp[2] = '\0';
7376
Fred Drake4d1e64b2002-04-15 19:40:07 +00007377 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007378}
7379#endif
7380
Barry Warsaw4a342091996-12-19 23:50:02 +00007381static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007382all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007383{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007384#ifdef F_OK
7385 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007386#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007387#ifdef R_OK
7388 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007389#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007390#ifdef W_OK
7391 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007392#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007393#ifdef X_OK
7394 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007395#endif
Fred Drakec9680921999-12-13 16:37:25 +00007396#ifdef NGROUPS_MAX
7397 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7398#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007399#ifdef TMP_MAX
7400 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7401#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007402#ifdef WCONTINUED
7403 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7404#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007405#ifdef WNOHANG
7406 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007407#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007408#ifdef WUNTRACED
7409 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7410#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007411#ifdef O_RDONLY
7412 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7413#endif
7414#ifdef O_WRONLY
7415 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7416#endif
7417#ifdef O_RDWR
7418 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7419#endif
7420#ifdef O_NDELAY
7421 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7422#endif
7423#ifdef O_NONBLOCK
7424 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7425#endif
7426#ifdef O_APPEND
7427 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7428#endif
7429#ifdef O_DSYNC
7430 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7431#endif
7432#ifdef O_RSYNC
7433 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7434#endif
7435#ifdef O_SYNC
7436 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7437#endif
7438#ifdef O_NOCTTY
7439 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7440#endif
7441#ifdef O_CREAT
7442 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7443#endif
7444#ifdef O_EXCL
7445 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7446#endif
7447#ifdef O_TRUNC
7448 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7449#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007450#ifdef O_BINARY
7451 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7452#endif
7453#ifdef O_TEXT
7454 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7455#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007456#ifdef O_LARGEFILE
7457 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7458#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007459#ifdef O_SHLOCK
7460 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7461#endif
7462#ifdef O_EXLOCK
7463 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7464#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007465
Tim Peters5aa91602002-01-30 05:46:57 +00007466/* MS Windows */
7467#ifdef O_NOINHERIT
7468 /* Don't inherit in child processes. */
7469 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7470#endif
7471#ifdef _O_SHORT_LIVED
7472 /* Optimize for short life (keep in memory). */
7473 /* MS forgot to define this one with a non-underscore form too. */
7474 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7475#endif
7476#ifdef O_TEMPORARY
7477 /* Automatically delete when last handle is closed. */
7478 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7479#endif
7480#ifdef O_RANDOM
7481 /* Optimize for random access. */
7482 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7483#endif
7484#ifdef O_SEQUENTIAL
7485 /* Optimize for sequential access. */
7486 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7487#endif
7488
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007489/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007490#ifdef O_ASYNC
7491 /* Send a SIGIO signal whenever input or output
7492 becomes available on file descriptor */
7493 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
7494#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007495#ifdef O_DIRECT
7496 /* Direct disk access. */
7497 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7498#endif
7499#ifdef O_DIRECTORY
7500 /* Must be a directory. */
7501 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7502#endif
7503#ifdef O_NOFOLLOW
7504 /* Do not follow links. */
7505 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7506#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007507#ifdef O_NOATIME
7508 /* Do not update the access time. */
7509 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
7510#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007511
Barry Warsaw5676bd12003-01-07 20:57:09 +00007512 /* These come from sysexits.h */
7513#ifdef EX_OK
7514 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007515#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007516#ifdef EX_USAGE
7517 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007518#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007519#ifdef EX_DATAERR
7520 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007521#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007522#ifdef EX_NOINPUT
7523 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007524#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007525#ifdef EX_NOUSER
7526 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007527#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007528#ifdef EX_NOHOST
7529 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007530#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007531#ifdef EX_UNAVAILABLE
7532 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007533#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007534#ifdef EX_SOFTWARE
7535 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007536#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007537#ifdef EX_OSERR
7538 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007539#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007540#ifdef EX_OSFILE
7541 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007542#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007543#ifdef EX_CANTCREAT
7544 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007545#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007546#ifdef EX_IOERR
7547 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007548#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007549#ifdef EX_TEMPFAIL
7550 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007551#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007552#ifdef EX_PROTOCOL
7553 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007554#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007555#ifdef EX_NOPERM
7556 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007557#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007558#ifdef EX_CONFIG
7559 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007560#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007561#ifdef EX_NOTFOUND
7562 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007563#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007564
Guido van Rossum246bc171999-02-01 23:54:31 +00007565#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007566#if defined(PYOS_OS2) && defined(PYCC_GCC)
7567 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7568 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7569 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7570 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7571 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7572 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7573 if (ins(d, "P_PM", (long)P_PM)) return -1;
7574 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7575 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7576 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7577 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7578 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7579 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7580 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7581 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7582 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7583 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7584 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7585 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7586 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7587#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007588 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7589 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7590 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7591 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7592 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007593#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007594#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007595
Guido van Rossumd48f2521997-12-05 22:19:34 +00007596#if defined(PYOS_OS2)
7597 if (insertvalues(d)) return -1;
7598#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007599 return 0;
7600}
7601
7602
Tim Peters5aa91602002-01-30 05:46:57 +00007603#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007604#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007605#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007606
7607#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007608#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007609#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007610
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007611#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00007612#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007613#define MODNAME "posix"
7614#endif
7615
Martin v. Löwis1a214512008-06-11 05:26:20 +00007616static struct PyModuleDef posixmodule = {
7617 PyModuleDef_HEAD_INIT,
7618 MODNAME,
7619 posix__doc__,
7620 -1,
7621 posix_methods,
7622 NULL,
7623 NULL,
7624 NULL,
7625 NULL
7626};
7627
7628
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007629PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007630INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007631{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007632 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007633
Martin v. Löwis1a214512008-06-11 05:26:20 +00007634 m = PyModule_Create(&posixmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007635 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007636 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007637
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007638 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007639 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007640 Py_XINCREF(v);
7641 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007642 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00007643 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007644
Fred Drake4d1e64b2002-04-15 19:40:07 +00007645 if (all_ins(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007646 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00007647
Fred Drake4d1e64b2002-04-15 19:40:07 +00007648 if (setup_confname_tables(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007649 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00007650
Fred Drake4d1e64b2002-04-15 19:40:07 +00007651 Py_INCREF(PyExc_OSError);
7652 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007653
Guido van Rossumb3d39562000-01-31 18:41:26 +00007654#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007655 if (posix_putenv_garbage == NULL)
7656 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007657#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007658
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007659 if (!initialized) {
7660 stat_result_desc.name = MODNAME ".stat_result";
7661 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7662 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7663 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7664 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7665 structseq_new = StatResultType.tp_new;
7666 StatResultType.tp_new = statresult_new;
7667
7668 statvfs_result_desc.name = MODNAME ".statvfs_result";
7669 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007670#ifdef NEED_TICKS_PER_SECOND
7671# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
7672 ticks_per_second = sysconf(_SC_CLK_TCK);
7673# elif defined(HZ)
7674 ticks_per_second = HZ;
7675# else
7676 ticks_per_second = 60; /* magic fallback value; may be bogus */
7677# endif
7678#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007679 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007680 Py_INCREF((PyObject*) &StatResultType);
7681 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007682 Py_INCREF((PyObject*) &StatVFSResultType);
7683 PyModule_AddObject(m, "statvfs_result",
7684 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007685 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007686
7687#ifdef __APPLE__
7688 /*
7689 * Step 2 of weak-linking support on Mac OS X.
7690 *
7691 * The code below removes functions that are not available on the
7692 * currently active platform.
7693 *
7694 * This block allow one to use a python binary that was build on
7695 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7696 * OSX 10.4.
7697 */
7698#ifdef HAVE_FSTATVFS
7699 if (fstatvfs == NULL) {
7700 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007701 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007702 }
7703 }
7704#endif /* HAVE_FSTATVFS */
7705
7706#ifdef HAVE_STATVFS
7707 if (statvfs == NULL) {
7708 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007709 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007710 }
7711 }
7712#endif /* HAVE_STATVFS */
7713
7714# ifdef HAVE_LCHOWN
7715 if (lchown == NULL) {
7716 if (PyObject_DelAttrString(m, "lchown") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007717 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007718 }
7719 }
7720#endif /* HAVE_LCHOWN */
7721
7722
7723#endif /* __APPLE__ */
Martin v. Löwis1a214512008-06-11 05:26:20 +00007724 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007725
Guido van Rossumb6775db1994-08-01 11:34:53 +00007726}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007727
7728#ifdef __cplusplus
7729}
7730#endif