blob: 9d7fe238c5fc7e9640e0e6eeebd291c33b2a7740 [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
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000189extern int chown(const char *, uid_t, gid_t);
190extern char *getcwd(char *, int);
191extern char *strerror(int);
192extern int link(const char *, const char *);
193extern int rename(const char *, const char *);
194extern int stat(const char *, struct stat *);
195extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000197extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000198#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000199#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000201#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000203
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#ifdef HAVE_UTIME_H
207#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000208#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000210#ifdef HAVE_SYS_UTIME_H
211#include <sys/utime.h>
212#define HAVE_UTIME_H /* pretend we do for the rest of this file */
213#endif /* HAVE_SYS_UTIME_H */
214
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#ifdef HAVE_SYS_TIMES_H
216#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000217#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218
219#ifdef HAVE_SYS_PARAM_H
220#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000221#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222
223#ifdef HAVE_SYS_UTSNAME_H
224#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000225#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000227#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000229#define NAMLEN(dirent) strlen((dirent)->d_name)
230#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000231#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#include <direct.h>
233#define NAMLEN(dirent) strlen((dirent)->d_name)
234#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000236#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000237#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000238#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000240#endif
241#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000243#endif
244#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000250#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000252#endif
253#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000255#endif
256#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000259#include "osdefs.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000261#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000262#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
Guido van Rossumd48f2521997-12-05 22:19:34 +0000264#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000266#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267
Tim Petersbc2e10e2002-03-03 23:17:02 +0000268#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000269#if defined(PATH_MAX) && PATH_MAX > 1024
270#define MAXPATHLEN PATH_MAX
271#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000272#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000273#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000274#endif /* MAXPATHLEN */
275
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000276#ifdef UNION_WAIT
277/* Emulate some macros on systems that have a union instead of macros */
278
279#ifndef WIFEXITED
280#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
281#endif
282
283#ifndef WEXITSTATUS
284#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
285#endif
286
287#ifndef WTERMSIG
288#define WTERMSIG(u_wait) ((u_wait).w_termsig)
289#endif
290
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000291#define WAIT_TYPE union wait
292#define WAIT_STATUS_INT(s) (s.w_status)
293
294#else /* !UNION_WAIT */
295#define WAIT_TYPE int
296#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000297#endif /* UNION_WAIT */
298
Greg Wardb48bc172000-03-01 21:51:56 +0000299/* Don't use the "_r" form if we don't need it (also, won't have a
300 prototype for it, at least on Solaris -- maybe others as well?). */
301#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
302#define USE_CTERMID_R
303#endif
304
Fred Drake699f3522000-06-29 21:12:41 +0000305/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000306#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000307#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000308# define STAT win32_stat
309# define FSTAT win32_fstat
310# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000311#else
312# define STAT stat
313# define FSTAT fstat
314# define STRUCT_STAT struct stat
315#endif
316
Tim Peters11b23062003-04-23 02:39:17 +0000317#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000318#include <sys/mkdev.h>
319#else
320#if defined(MAJOR_IN_SYSMACROS)
321#include <sys/sysmacros.h>
322#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000323#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
324#include <sys/mkdev.h>
325#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000326#endif
Fred Drake699f3522000-06-29 21:12:41 +0000327
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000329#ifdef WITH_NEXT_FRAMEWORK
330/* On Darwin/MacOSX a shared library or framework has no access to
331** environ directly, we must obtain it with _NSGetEnviron().
332*/
333#include <crt_externs.h>
334static char **environ;
335#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000336extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000337#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Barry Warsaw53699e91996-12-10 23:23:01 +0000339static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000340convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341{
Barry Warsaw53699e91996-12-10 23:23:01 +0000342 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000343#ifdef MS_WINDOWS
344 wchar_t **e;
345#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000347#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000348 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349 if (d == NULL)
350 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000351#ifdef WITH_NEXT_FRAMEWORK
352 if (environ == NULL)
353 environ = *_NSGetEnviron();
354#endif
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000355#ifdef MS_WINDOWS
356 /* _wenviron must be initialized in this way if the program is started
357 through main() instead of wmain(). */
358 _wgetenv(L"");
359 if (_wenviron == NULL)
360 return d;
361 /* This part ignores errors */
362 for (e = _wenviron; *e != NULL; e++) {
363 PyObject *k;
364 PyObject *v;
365 wchar_t *p = wcschr(*e, L'=');
366 if (p == NULL)
367 continue;
368 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
369 if (k == NULL) {
370 PyErr_Clear();
371 continue;
372 }
373 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
374 if (v == NULL) {
375 PyErr_Clear();
376 Py_DECREF(k);
377 continue;
378 }
379 if (PyDict_GetItem(d, k) == NULL) {
380 if (PyDict_SetItem(d, k, v) != 0)
381 PyErr_Clear();
382 }
383 Py_DECREF(k);
384 Py_DECREF(v);
385 }
386#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000387 if (environ == NULL)
388 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000389 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000390 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000391 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000392 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393 char *p = strchr(*e, '=');
394 if (p == NULL)
395 continue;
Guido van Rossum98297ee2007-11-06 21:34:58 +0000396 k = PyUnicode_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000397 if (k == NULL) {
398 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000399 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000400 }
Guido van Rossum98297ee2007-11-06 21:34:58 +0000401 v = PyUnicode_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000402 if (v == NULL) {
403 PyErr_Clear();
404 Py_DECREF(k);
405 continue;
406 }
407 if (PyDict_GetItem(d, k) == NULL) {
408 if (PyDict_SetItem(d, k, v) != 0)
409 PyErr_Clear();
410 }
411 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000412 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000414#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000415#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000416 {
417 APIRET rc;
418 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
419
420 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000421 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000422 PyObject *v = PyString_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000423 PyDict_SetItemString(d, "BEGINLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000424 Py_DECREF(v);
425 }
426 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
427 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
428 PyObject *v = PyString_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000429 PyDict_SetItemString(d, "ENDLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000430 Py_DECREF(v);
431 }
432 }
433#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000434 return d;
435}
436
437
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000438/* Set a POSIX-specific error from errno, and return NULL */
439
Barry Warsawd58d7641998-07-23 16:14:40 +0000440static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000441posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000442{
Barry Warsawca74da41999-02-09 19:31:45 +0000443 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444}
Barry Warsawd58d7641998-07-23 16:14:40 +0000445static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000446posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000447{
Barry Warsawca74da41999-02-09 19:31:45 +0000448 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000449}
450
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000451#ifdef Py_WIN_WIDE_FILENAMES
452static PyObject *
453posix_error_with_unicode_filename(Py_UNICODE* name)
454{
455 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
456}
457#endif /* Py_WIN_WIDE_FILENAMES */
458
459
Mark Hammondef8b6542001-05-13 08:04:26 +0000460static PyObject *
461posix_error_with_allocated_filename(char* name)
462{
463 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
464 PyMem_Free(name);
465 return rc;
466}
467
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000468#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000469static PyObject *
470win32_error(char* function, char* filename)
471{
Mark Hammond33a6da92000-08-15 00:46:38 +0000472 /* XXX We should pass the function name along in the future.
473 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000474 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000475 Windows error object, which is non-trivial.
476 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000477 errno = GetLastError();
478 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000479 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000480 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000481 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000482}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000483
484#ifdef Py_WIN_WIDE_FILENAMES
485static PyObject *
486win32_error_unicode(char* function, Py_UNICODE* filename)
487{
488 /* XXX - see win32_error for comments on 'function' */
489 errno = GetLastError();
490 if (filename)
491 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
492 else
493 return PyErr_SetFromWindowsErr(errno);
494}
495
496static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
497{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000498}
499
500/* Function suitable for O& conversion */
501static int
502convert_to_unicode(PyObject *arg, void* _param)
503{
504 PyObject **param = (PyObject**)_param;
505 if (PyUnicode_CheckExact(arg)) {
506 Py_INCREF(arg);
507 *param = arg;
508 }
509 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000510 /* For a Unicode subtype that's not a Unicode object,
511 return a true Unicode object with the same data. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000512 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
513 PyUnicode_GET_SIZE(arg));
514 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000515 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000516 else
517 *param = PyUnicode_FromEncodedObject(arg,
518 Py_FileSystemDefaultEncoding,
519 "strict");
520 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000521}
522
523#endif /* Py_WIN_WIDE_FILENAMES */
524
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000525#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000526
Guido van Rossumd48f2521997-12-05 22:19:34 +0000527#if defined(PYOS_OS2)
528/**********************************************************************
529 * Helper Function to Trim and Format OS/2 Messages
530 **********************************************************************/
531 static void
532os2_formatmsg(char *msgbuf, int msglen, char *reason)
533{
534 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
535
536 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
537 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
538
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000539 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000540 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
541 }
542
543 /* Add Optional Reason Text */
544 if (reason) {
545 strcat(msgbuf, " : ");
546 strcat(msgbuf, reason);
547 }
548}
549
550/**********************************************************************
551 * Decode an OS/2 Operating System Error Code
552 *
553 * A convenience function to lookup an OS/2 error code and return a
554 * text message we can use to raise a Python exception.
555 *
556 * Notes:
557 * The messages for errors returned from the OS/2 kernel reside in
558 * the file OSO001.MSG in the \OS2 directory hierarchy.
559 *
560 **********************************************************************/
561 static char *
562os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
563{
564 APIRET rc;
565 ULONG msglen;
566
567 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
568 Py_BEGIN_ALLOW_THREADS
569 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
570 errorcode, "oso001.msg", &msglen);
571 Py_END_ALLOW_THREADS
572
573 if (rc == NO_ERROR)
574 os2_formatmsg(msgbuf, msglen, reason);
575 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000576 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000577 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000578
579 return msgbuf;
580}
581
582/* Set an OS/2-specific error and return NULL. OS/2 kernel
583 errors are not in a global variable e.g. 'errno' nor are
584 they congruent with posix error numbers. */
585
586static PyObject * os2_error(int code)
587{
588 char text[1024];
589 PyObject *v;
590
591 os2_strerror(text, sizeof(text), code, "");
592
593 v = Py_BuildValue("(is)", code, text);
594 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000595 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000596 Py_DECREF(v);
597 }
598 return NULL; /* Signal to Python that an Exception is Pending */
599}
600
601#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000602
603/* POSIX generic methods */
604
Barry Warsaw53699e91996-12-10 23:23:01 +0000605static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000606posix_fildes(PyObject *fdobj, int (*func)(int))
607{
608 int fd;
609 int res;
610 fd = PyObject_AsFileDescriptor(fdobj);
611 if (fd < 0)
612 return NULL;
613 Py_BEGIN_ALLOW_THREADS
614 res = (*func)(fd);
615 Py_END_ALLOW_THREADS
616 if (res < 0)
617 return posix_error();
618 Py_INCREF(Py_None);
619 return Py_None;
620}
Guido van Rossum21142a01999-01-08 21:05:37 +0000621
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000622#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000623static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000624unicode_file_names(void)
625{
626 static int canusewide = -1;
627 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000628 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000629 the Windows NT family. */
630 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
631 }
632 return canusewide;
633}
634#endif
Tim Peters11b23062003-04-23 02:39:17 +0000635
Guido van Rossum21142a01999-01-08 21:05:37 +0000636static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000637posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000638{
Mark Hammondef8b6542001-05-13 08:04:26 +0000639 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000640 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000641 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000642 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000643 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000644 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000645 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000646 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000647 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000648 return posix_error_with_allocated_filename(path1);
649 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000650 Py_INCREF(Py_None);
651 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000652}
653
Barry Warsaw53699e91996-12-10 23:23:01 +0000654static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000655posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000656 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000657 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658{
Mark Hammondef8b6542001-05-13 08:04:26 +0000659 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000660 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000661 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000662 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000663 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000665 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000666 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000667 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000668 PyMem_Free(path1);
669 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000670 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000671 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000672 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000673 Py_INCREF(Py_None);
674 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000675}
676
Thomas Wouters477c8d52006-05-27 19:21:47 +0000677#ifdef Py_WIN_WIDE_FILENAMES
678static PyObject*
679win32_1str(PyObject* args, char* func,
680 char* format, BOOL (__stdcall *funcA)(LPCSTR),
681 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
682{
683 PyObject *uni;
684 char *ansi;
685 BOOL result;
686 if (unicode_file_names()) {
687 if (!PyArg_ParseTuple(args, wformat, &uni))
688 PyErr_Clear();
689 else {
690 Py_BEGIN_ALLOW_THREADS
691 result = funcW(PyUnicode_AsUnicode(uni));
692 Py_END_ALLOW_THREADS
693 if (!result)
694 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
695 Py_INCREF(Py_None);
696 return Py_None;
697 }
698 }
699 if (!PyArg_ParseTuple(args, format, &ansi))
700 return NULL;
701 Py_BEGIN_ALLOW_THREADS
702 result = funcA(ansi);
703 Py_END_ALLOW_THREADS
704 if (!result)
705 return win32_error(func, ansi);
706 Py_INCREF(Py_None);
707 return Py_None;
708
709}
710
711/* This is a reimplementation of the C library's chdir function,
712 but one that produces Win32 errors instead of DOS error codes.
713 chdir is essentially a wrapper around SetCurrentDirectory; however,
714 it also needs to set "magic" environment variables indicating
715 the per-drive current directory, which are of the form =<drive>: */
716BOOL __stdcall
717win32_chdir(LPCSTR path)
718{
719 char new_path[MAX_PATH+1];
720 int result;
721 char env[4] = "=x:";
722
723 if(!SetCurrentDirectoryA(path))
724 return FALSE;
725 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
726 if (!result)
727 return FALSE;
728 /* In the ANSI API, there should not be any paths longer
729 than MAX_PATH. */
730 assert(result <= MAX_PATH+1);
731 if (strncmp(new_path, "\\\\", 2) == 0 ||
732 strncmp(new_path, "//", 2) == 0)
733 /* UNC path, nothing to do. */
734 return TRUE;
735 env[1] = new_path[0];
736 return SetEnvironmentVariableA(env, new_path);
737}
738
739/* The Unicode version differs from the ANSI version
740 since the current directory might exceed MAX_PATH characters */
741BOOL __stdcall
742win32_wchdir(LPCWSTR path)
743{
744 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
745 int result;
746 wchar_t env[4] = L"=x:";
747
748 if(!SetCurrentDirectoryW(path))
749 return FALSE;
750 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
751 if (!result)
752 return FALSE;
753 if (result > MAX_PATH+1) {
754 new_path = malloc(result);
755 if (!new_path) {
756 SetLastError(ERROR_OUTOFMEMORY);
757 return FALSE;
758 }
759 }
760 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
761 wcsncmp(new_path, L"//", 2) == 0)
762 /* UNC path, nothing to do. */
763 return TRUE;
764 env[1] = new_path[0];
765 result = SetEnvironmentVariableW(env, new_path);
766 if (new_path != _new_path)
767 free(new_path);
768 return result;
769}
770#endif
771
Martin v. Löwis14694662006-02-03 12:54:16 +0000772#ifdef MS_WINDOWS
773/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
774 - time stamps are restricted to second resolution
775 - file modification times suffer from forth-and-back conversions between
776 UTC and local time
777 Therefore, we implement our own stat, based on the Win32 API directly.
778*/
779#define HAVE_STAT_NSEC 1
780
781struct win32_stat{
782 int st_dev;
783 __int64 st_ino;
784 unsigned short st_mode;
785 int st_nlink;
786 int st_uid;
787 int st_gid;
788 int st_rdev;
789 __int64 st_size;
790 int st_atime;
791 int st_atime_nsec;
792 int st_mtime;
793 int st_mtime_nsec;
794 int st_ctime;
795 int st_ctime_nsec;
796};
797
798static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
799
800static void
801FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
802{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
804 /* Cannot simply cast and dereference in_ptr,
805 since it might not be aligned properly */
806 __int64 in;
807 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000808 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
809 /* XXX Win32 supports time stamps past 2038; we currently don't */
810 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
811}
812
Thomas Wouters477c8d52006-05-27 19:21:47 +0000813static void
814time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
815{
816 /* XXX endianness */
817 __int64 out;
818 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000819 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820 memcpy(out_ptr, &out, sizeof(out));
821}
822
Martin v. Löwis14694662006-02-03 12:54:16 +0000823/* Below, we *know* that ugo+r is 0444 */
824#if _S_IREAD != 0400
825#error Unsupported C library
826#endif
827static int
828attributes_to_mode(DWORD attr)
829{
830 int m = 0;
831 if (attr & FILE_ATTRIBUTE_DIRECTORY)
832 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
833 else
834 m |= _S_IFREG;
835 if (attr & FILE_ATTRIBUTE_READONLY)
836 m |= 0444;
837 else
838 m |= 0666;
839 return m;
840}
841
842static int
843attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
844{
845 memset(result, 0, sizeof(*result));
846 result->st_mode = attributes_to_mode(info->dwFileAttributes);
847 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
848 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
849 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
850 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
851
852 return 0;
853}
854
Thomas Wouters89f507f2006-12-13 04:49:30 +0000855/* Emulate GetFileAttributesEx[AW] on Windows 95 */
856static int checked = 0;
857static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
858static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
859static void
860check_gfax()
861{
862 HINSTANCE hKernel32;
863 if (checked)
864 return;
865 checked = 1;
866 hKernel32 = GetModuleHandle("KERNEL32");
867 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
868 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
869}
870
Guido van Rossumd8faa362007-04-27 19:54:29 +0000871static BOOL
872attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
873{
874 HANDLE hFindFile;
875 WIN32_FIND_DATAA FileData;
876 hFindFile = FindFirstFileA(pszFile, &FileData);
877 if (hFindFile == INVALID_HANDLE_VALUE)
878 return FALSE;
879 FindClose(hFindFile);
880 pfad->dwFileAttributes = FileData.dwFileAttributes;
881 pfad->ftCreationTime = FileData.ftCreationTime;
882 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
883 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
884 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
885 pfad->nFileSizeLow = FileData.nFileSizeLow;
886 return TRUE;
887}
888
889static BOOL
890attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
891{
892 HANDLE hFindFile;
893 WIN32_FIND_DATAW FileData;
894 hFindFile = FindFirstFileW(pszFile, &FileData);
895 if (hFindFile == INVALID_HANDLE_VALUE)
896 return FALSE;
897 FindClose(hFindFile);
898 pfad->dwFileAttributes = FileData.dwFileAttributes;
899 pfad->ftCreationTime = FileData.ftCreationTime;
900 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
901 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
902 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
903 pfad->nFileSizeLow = FileData.nFileSizeLow;
904 return TRUE;
905}
906
Thomas Wouters89f507f2006-12-13 04:49:30 +0000907static BOOL WINAPI
908Py_GetFileAttributesExA(LPCSTR pszFile,
909 GET_FILEEX_INFO_LEVELS level,
910 LPVOID pv)
911{
912 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000913 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
914 /* First try to use the system's implementation, if that is
915 available and either succeeds to gives an error other than
916 that it isn't implemented. */
917 check_gfax();
918 if (gfaxa) {
919 result = gfaxa(pszFile, level, pv);
920 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
921 return result;
922 }
923 /* It's either not present, or not implemented.
924 Emulate using FindFirstFile. */
925 if (level != GetFileExInfoStandard) {
926 SetLastError(ERROR_INVALID_PARAMETER);
927 return FALSE;
928 }
929 /* Use GetFileAttributes to validate that the file name
930 does not contain wildcards (which FindFirstFile would
931 accept). */
932 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
933 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000934 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000935}
936
937static BOOL WINAPI
938Py_GetFileAttributesExW(LPCWSTR pszFile,
939 GET_FILEEX_INFO_LEVELS level,
940 LPVOID pv)
941{
942 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000943 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
944 /* First try to use the system's implementation, if that is
945 available and either succeeds to gives an error other than
946 that it isn't implemented. */
947 check_gfax();
948 if (gfaxa) {
949 result = gfaxw(pszFile, level, pv);
950 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
951 return result;
952 }
953 /* It's either not present, or not implemented.
954 Emulate using FindFirstFile. */
955 if (level != GetFileExInfoStandard) {
956 SetLastError(ERROR_INVALID_PARAMETER);
957 return FALSE;
958 }
959 /* Use GetFileAttributes to validate that the file name
960 does not contain wildcards (which FindFirstFile would
961 accept). */
962 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
963 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000964 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000965}
966
Martin v. Löwis14694662006-02-03 12:54:16 +0000967static int
968win32_stat(const char* path, struct win32_stat *result)
969{
970 WIN32_FILE_ATTRIBUTE_DATA info;
971 int code;
972 char *dot;
973 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000974 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000975 if (GetLastError() != ERROR_SHARING_VIOLATION) {
976 /* Protocol violation: we explicitly clear errno, instead of
977 setting it to a POSIX error. Callers should use GetLastError. */
978 errno = 0;
979 return -1;
980 } else {
981 /* Could not get attributes on open file. Fall back to
982 reading the directory. */
983 if (!attributes_from_dir(path, &info)) {
984 /* Very strange. This should not fail now */
985 errno = 0;
986 return -1;
987 }
988 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000989 }
990 code = attribute_data_to_stat(&info, result);
991 if (code != 0)
992 return code;
993 /* Set S_IFEXEC if it is an .exe, .bat, ... */
994 dot = strrchr(path, '.');
995 if (dot) {
996 if (stricmp(dot, ".bat") == 0 ||
997 stricmp(dot, ".cmd") == 0 ||
998 stricmp(dot, ".exe") == 0 ||
999 stricmp(dot, ".com") == 0)
1000 result->st_mode |= 0111;
1001 }
1002 return code;
1003}
1004
1005static int
1006win32_wstat(const wchar_t* path, struct win32_stat *result)
1007{
1008 int code;
1009 const wchar_t *dot;
1010 WIN32_FILE_ATTRIBUTE_DATA info;
1011 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001012 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001013 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1014 /* Protocol violation: we explicitly clear errno, instead of
1015 setting it to a POSIX error. Callers should use GetLastError. */
1016 errno = 0;
1017 return -1;
1018 } else {
1019 /* Could not get attributes on open file. Fall back to
1020 reading the directory. */
1021 if (!attributes_from_dir_w(path, &info)) {
1022 /* Very strange. This should not fail now */
1023 errno = 0;
1024 return -1;
1025 }
1026 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001027 }
1028 code = attribute_data_to_stat(&info, result);
1029 if (code < 0)
1030 return code;
1031 /* Set IFEXEC if it is an .exe, .bat, ... */
1032 dot = wcsrchr(path, '.');
1033 if (dot) {
1034 if (_wcsicmp(dot, L".bat") == 0 ||
1035 _wcsicmp(dot, L".cmd") == 0 ||
1036 _wcsicmp(dot, L".exe") == 0 ||
1037 _wcsicmp(dot, L".com") == 0)
1038 result->st_mode |= 0111;
1039 }
1040 return code;
1041}
1042
1043static int
1044win32_fstat(int file_number, struct win32_stat *result)
1045{
1046 BY_HANDLE_FILE_INFORMATION info;
1047 HANDLE h;
1048 int type;
1049
1050 h = (HANDLE)_get_osfhandle(file_number);
1051
1052 /* Protocol violation: we explicitly clear errno, instead of
1053 setting it to a POSIX error. Callers should use GetLastError. */
1054 errno = 0;
1055
1056 if (h == INVALID_HANDLE_VALUE) {
1057 /* This is really a C library error (invalid file handle).
1058 We set the Win32 error to the closes one matching. */
1059 SetLastError(ERROR_INVALID_HANDLE);
1060 return -1;
1061 }
1062 memset(result, 0, sizeof(*result));
1063
1064 type = GetFileType(h);
1065 if (type == FILE_TYPE_UNKNOWN) {
1066 DWORD error = GetLastError();
1067 if (error != 0) {
1068 return -1;
1069 }
1070 /* else: valid but unknown file */
1071 }
1072
1073 if (type != FILE_TYPE_DISK) {
1074 if (type == FILE_TYPE_CHAR)
1075 result->st_mode = _S_IFCHR;
1076 else if (type == FILE_TYPE_PIPE)
1077 result->st_mode = _S_IFIFO;
1078 return 0;
1079 }
1080
1081 if (!GetFileInformationByHandle(h, &info)) {
1082 return -1;
1083 }
1084
1085 /* similar to stat() */
1086 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1087 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1088 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1089 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1090 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1091 /* specific to fstat() */
1092 result->st_nlink = info.nNumberOfLinks;
1093 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1094 return 0;
1095}
1096
1097#endif /* MS_WINDOWS */
1098
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001099PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001100"stat_result: Result from stat or lstat.\n\n\
1101This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001102 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001103or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1104\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001105Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1106or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001107\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001108See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001109
1110static PyStructSequence_Field stat_result_fields[] = {
1111 {"st_mode", "protection bits"},
1112 {"st_ino", "inode"},
1113 {"st_dev", "device"},
1114 {"st_nlink", "number of hard links"},
1115 {"st_uid", "user ID of owner"},
1116 {"st_gid", "group ID of owner"},
1117 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001118 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1119 {NULL, "integer time of last access"},
1120 {NULL, "integer time of last modification"},
1121 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001122 {"st_atime", "time of last access"},
1123 {"st_mtime", "time of last modification"},
1124 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001125#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001126 {"st_blksize", "blocksize for filesystem I/O"},
1127#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001128#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001129 {"st_blocks", "number of blocks allocated"},
1130#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001131#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001132 {"st_rdev", "device type (if inode device)"},
1133#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001134#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1135 {"st_flags", "user defined flags for file"},
1136#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001137#ifdef HAVE_STRUCT_STAT_ST_GEN
1138 {"st_gen", "generation number"},
1139#endif
1140#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1141 {"st_birthtime", "time of creation"},
1142#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001143 {0}
1144};
1145
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001146#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001147#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001148#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001149#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001150#endif
1151
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001152#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001153#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1154#else
1155#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1156#endif
1157
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001158#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001159#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1160#else
1161#define ST_RDEV_IDX ST_BLOCKS_IDX
1162#endif
1163
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001164#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1165#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1166#else
1167#define ST_FLAGS_IDX ST_RDEV_IDX
1168#endif
1169
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001170#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001171#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001172#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001173#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001174#endif
1175
1176#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1177#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1178#else
1179#define ST_BIRTHTIME_IDX ST_GEN_IDX
1180#endif
1181
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001182static PyStructSequence_Desc stat_result_desc = {
1183 "stat_result", /* name */
1184 stat_result__doc__, /* doc */
1185 stat_result_fields,
1186 10
1187};
1188
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001189PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001190"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1191This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001192 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001193or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001194\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001195See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001196
1197static PyStructSequence_Field statvfs_result_fields[] = {
1198 {"f_bsize", },
1199 {"f_frsize", },
1200 {"f_blocks", },
1201 {"f_bfree", },
1202 {"f_bavail", },
1203 {"f_files", },
1204 {"f_ffree", },
1205 {"f_favail", },
1206 {"f_flag", },
1207 {"f_namemax",},
1208 {0}
1209};
1210
1211static PyStructSequence_Desc statvfs_result_desc = {
1212 "statvfs_result", /* name */
1213 statvfs_result__doc__, /* doc */
1214 statvfs_result_fields,
1215 10
1216};
1217
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001218static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001219static PyTypeObject StatResultType;
1220static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001221static newfunc structseq_new;
1222
1223static PyObject *
1224statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1225{
1226 PyStructSequence *result;
1227 int i;
1228
1229 result = (PyStructSequence*)structseq_new(type, args, kwds);
1230 if (!result)
1231 return NULL;
1232 /* If we have been initialized from a tuple,
1233 st_?time might be set to None. Initialize it
1234 from the int slots. */
1235 for (i = 7; i <= 9; i++) {
1236 if (result->ob_item[i+3] == Py_None) {
1237 Py_DECREF(Py_None);
1238 Py_INCREF(result->ob_item[i]);
1239 result->ob_item[i+3] = result->ob_item[i];
1240 }
1241 }
1242 return (PyObject*)result;
1243}
1244
1245
1246
1247/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001248static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001249
1250PyDoc_STRVAR(stat_float_times__doc__,
1251"stat_float_times([newval]) -> oldval\n\n\
1252Determine whether os.[lf]stat represents time stamps as float objects.\n\
1253If newval is True, future calls to stat() return floats, if it is False,\n\
1254future calls return ints. \n\
1255If newval is omitted, return the current setting.\n");
1256
1257static PyObject*
1258stat_float_times(PyObject* self, PyObject *args)
1259{
1260 int newval = -1;
1261 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1262 return NULL;
1263 if (newval == -1)
1264 /* Return old value */
1265 return PyBool_FromLong(_stat_float_times);
1266 _stat_float_times = newval;
1267 Py_INCREF(Py_None);
1268 return Py_None;
1269}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001270
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001271static void
1272fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1273{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001274 PyObject *fval,*ival;
1275#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001276 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001277#else
1278 ival = PyInt_FromLong((long)sec);
1279#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001280 if (!ival)
1281 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001282 if (_stat_float_times) {
1283 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1284 } else {
1285 fval = ival;
1286 Py_INCREF(fval);
1287 }
1288 PyStructSequence_SET_ITEM(v, index, ival);
1289 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001290}
1291
Tim Peters5aa91602002-01-30 05:46:57 +00001292/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001293 (used by posix_stat() and posix_fstat()) */
1294static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001295_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001296{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001297 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001298 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001299 if (v == NULL)
1300 return NULL;
1301
Martin v. Löwis14694662006-02-03 12:54:16 +00001302 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001303#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001304 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001305 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001306#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001307 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001308#endif
1309#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001310 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001311 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001312#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001313 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001314#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001315 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1316 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1317 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001318#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001319 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001320 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001321#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001322 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001323#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001324
Martin v. Löwis14694662006-02-03 12:54:16 +00001325#if defined(HAVE_STAT_TV_NSEC)
1326 ansec = st->st_atim.tv_nsec;
1327 mnsec = st->st_mtim.tv_nsec;
1328 cnsec = st->st_ctim.tv_nsec;
1329#elif defined(HAVE_STAT_TV_NSEC2)
1330 ansec = st->st_atimespec.tv_nsec;
1331 mnsec = st->st_mtimespec.tv_nsec;
1332 cnsec = st->st_ctimespec.tv_nsec;
1333#elif defined(HAVE_STAT_NSEC)
1334 ansec = st->st_atime_nsec;
1335 mnsec = st->st_mtime_nsec;
1336 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001337#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001338 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001339#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001340 fill_time(v, 7, st->st_atime, ansec);
1341 fill_time(v, 8, st->st_mtime, mnsec);
1342 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001343
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001344#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001345 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001346 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001347#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001348#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001349 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001350 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001351#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001352#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001353 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001354 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001355#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001356#ifdef HAVE_STRUCT_STAT_ST_GEN
1357 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001358 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001359#endif
1360#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1361 {
1362 PyObject *val;
1363 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001364 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001365#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001366 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001367#else
1368 bnsec = 0;
1369#endif
1370 if (_stat_float_times) {
1371 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1372 } else {
1373 val = PyInt_FromLong((long)bsec);
1374 }
1375 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1376 val);
1377 }
1378#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001379#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1380 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001381 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001382#endif
Fred Drake699f3522000-06-29 21:12:41 +00001383
1384 if (PyErr_Occurred()) {
1385 Py_DECREF(v);
1386 return NULL;
1387 }
1388
1389 return v;
1390}
1391
Martin v. Löwisd8948722004-06-02 09:57:56 +00001392#ifdef MS_WINDOWS
1393
1394/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1395 where / can be used in place of \ and the trailing slash is optional.
1396 Both SERVER and SHARE must have at least one character.
1397*/
1398
1399#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1400#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001401#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001402#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001403#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001404
Tim Peters4ad82172004-08-30 17:02:04 +00001405static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001406IsUNCRootA(char *path, int pathlen)
1407{
1408 #define ISSLASH ISSLASHA
1409
1410 int i, share;
1411
1412 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1413 /* minimum UNCRoot is \\x\y */
1414 return FALSE;
1415 for (i = 2; i < pathlen ; i++)
1416 if (ISSLASH(path[i])) break;
1417 if (i == 2 || i == pathlen)
1418 /* do not allow \\\SHARE or \\SERVER */
1419 return FALSE;
1420 share = i+1;
1421 for (i = share; i < pathlen; i++)
1422 if (ISSLASH(path[i])) break;
1423 return (i != share && (i == pathlen || i == pathlen-1));
1424
1425 #undef ISSLASH
1426}
1427
1428#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001429static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001430IsUNCRootW(Py_UNICODE *path, int pathlen)
1431{
1432 #define ISSLASH ISSLASHW
1433
1434 int i, share;
1435
1436 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1437 /* minimum UNCRoot is \\x\y */
1438 return FALSE;
1439 for (i = 2; i < pathlen ; i++)
1440 if (ISSLASH(path[i])) break;
1441 if (i == 2 || i == pathlen)
1442 /* do not allow \\\SHARE or \\SERVER */
1443 return FALSE;
1444 share = i+1;
1445 for (i = share; i < pathlen; i++)
1446 if (ISSLASH(path[i])) break;
1447 return (i != share && (i == pathlen || i == pathlen-1));
1448
1449 #undef ISSLASH
1450}
1451#endif /* Py_WIN_WIDE_FILENAMES */
1452#endif /* MS_WINDOWS */
1453
Barry Warsaw53699e91996-12-10 23:23:01 +00001454static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001455posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001456 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001457#ifdef __VMS
1458 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1459#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001460 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001461#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001462 char *wformat,
1463 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001464{
Fred Drake699f3522000-06-29 21:12:41 +00001465 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001466 char *path = NULL; /* pass this to stat; do not free() it */
1467 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001468 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001469 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001470
1471#ifdef Py_WIN_WIDE_FILENAMES
1472 /* If on wide-character-capable OS see if argument
1473 is Unicode and if so use wide API. */
1474 if (unicode_file_names()) {
1475 PyUnicodeObject *po;
1476 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001477 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1478
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001479 Py_BEGIN_ALLOW_THREADS
1480 /* PyUnicode_AS_UNICODE result OK without
1481 thread lock as it is a simple dereference. */
1482 res = wstatfunc(wpath, &st);
1483 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001484
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001485 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001486 return win32_error_unicode("stat", wpath);
1487 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001488 }
1489 /* Drop the argument parsing error as narrow strings
1490 are also valid. */
1491 PyErr_Clear();
1492 }
1493#endif
1494
Tim Peters5aa91602002-01-30 05:46:57 +00001495 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001496 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001497 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001498 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001499
Barry Warsaw53699e91996-12-10 23:23:01 +00001500 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001501 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001502 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001503
1504 if (res != 0) {
1505#ifdef MS_WINDOWS
1506 result = win32_error("stat", pathfree);
1507#else
1508 result = posix_error_with_filename(pathfree);
1509#endif
1510 }
1511 else
1512 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001513
Tim Peters500bd032001-12-19 19:05:01 +00001514 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001515 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001516}
1517
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001518/* POSIX methods */
1519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001520PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001521"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001522Use the real uid/gid to test for access to a path. Note that most\n\
1523operations will use the effective uid/gid, therefore this routine can\n\
1524be used in a suid/sgid environment to test if the invoking user has the\n\
1525specified access to the path. The mode argument can be F_OK to test\n\
1526existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001527
1528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001529posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001530{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001531 char *path;
1532 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001533
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001534#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001536 if (unicode_file_names()) {
1537 PyUnicodeObject *po;
1538 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1539 Py_BEGIN_ALLOW_THREADS
1540 /* PyUnicode_AS_UNICODE OK without thread lock as
1541 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001543 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001545 }
1546 /* Drop the argument parsing error as narrow strings
1547 are also valid. */
1548 PyErr_Clear();
1549 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550 if (!PyArg_ParseTuple(args, "eti:access",
1551 Py_FileSystemDefaultEncoding, &path, &mode))
1552 return 0;
1553 Py_BEGIN_ALLOW_THREADS
1554 attr = GetFileAttributesA(path);
1555 Py_END_ALLOW_THREADS
1556 PyMem_Free(path);
1557finish:
1558 if (attr == 0xFFFFFFFF)
1559 /* File does not exist, or cannot read attributes */
1560 return PyBool_FromLong(0);
1561 /* Access is possible if either write access wasn't requested, or
1562 the file isn't read-only. */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001563 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001564#else
1565 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001566 if (!PyArg_ParseTuple(args, "eti:access",
1567 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001568 return NULL;
1569 Py_BEGIN_ALLOW_THREADS
1570 res = access(path, mode);
1571 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001572 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001573 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001574#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001575}
1576
Guido van Rossumd371ff11999-01-25 16:12:23 +00001577#ifndef F_OK
1578#define F_OK 0
1579#endif
1580#ifndef R_OK
1581#define R_OK 4
1582#endif
1583#ifndef W_OK
1584#define W_OK 2
1585#endif
1586#ifndef X_OK
1587#define X_OK 1
1588#endif
1589
1590#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001591PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001592"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001593Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001594
1595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001596posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001597{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001598 int id;
1599 char *ret;
1600
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001601 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001602 return NULL;
1603
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001604#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001605 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001606 if (id == 0) {
1607 ret = ttyname();
1608 }
1609 else {
1610 ret = NULL;
1611 }
1612#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001613 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001614#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001615 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001616 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001617 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001618}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001619#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001620
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001621#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001622PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001623"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001624Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001625
1626static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001627posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001628{
1629 char *ret;
1630 char buffer[L_ctermid];
1631
Greg Wardb48bc172000-03-01 21:51:56 +00001632#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001633 ret = ctermid_r(buffer);
1634#else
1635 ret = ctermid(buffer);
1636#endif
1637 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001638 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001639 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001640}
1641#endif
1642
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001643PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001644"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001645Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001646
Barry Warsaw53699e91996-12-10 23:23:01 +00001647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001648posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001649{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001650#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001652#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001653 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001654#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001655 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001656#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001657 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001658#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001659}
1660
Fred Drake4d1e64b2002-04-15 19:40:07 +00001661#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001662PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001663"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001664Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001665opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001666
1667static PyObject *
1668posix_fchdir(PyObject *self, PyObject *fdobj)
1669{
1670 return posix_fildes(fdobj, fchdir);
1671}
1672#endif /* HAVE_FCHDIR */
1673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001674
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001675PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001676"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001677Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001678
Barry Warsaw53699e91996-12-10 23:23:01 +00001679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001680posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001681{
Mark Hammondef8b6542001-05-13 08:04:26 +00001682 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001683 int i;
1684 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001685#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001686 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001687 if (unicode_file_names()) {
1688 PyUnicodeObject *po;
1689 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1690 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001691 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1692 if (attr != 0xFFFFFFFF) {
1693 if (i & _S_IWRITE)
1694 attr &= ~FILE_ATTRIBUTE_READONLY;
1695 else
1696 attr |= FILE_ATTRIBUTE_READONLY;
1697 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1698 }
1699 else
1700 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001701 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001702 if (!res)
1703 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001704 PyUnicode_AS_UNICODE(po));
1705 Py_INCREF(Py_None);
1706 return Py_None;
1707 }
1708 /* Drop the argument parsing error as narrow strings
1709 are also valid. */
1710 PyErr_Clear();
1711 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001712 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1713 &path, &i))
1714 return NULL;
1715 Py_BEGIN_ALLOW_THREADS
1716 attr = GetFileAttributesA(path);
1717 if (attr != 0xFFFFFFFF) {
1718 if (i & _S_IWRITE)
1719 attr &= ~FILE_ATTRIBUTE_READONLY;
1720 else
1721 attr |= FILE_ATTRIBUTE_READONLY;
1722 res = SetFileAttributesA(path, attr);
1723 }
1724 else
1725 res = 0;
1726 Py_END_ALLOW_THREADS
1727 if (!res) {
1728 win32_error("chmod", path);
1729 PyMem_Free(path);
1730 return NULL;
1731 }
1732 PyMem_Free(path);
1733 Py_INCREF(Py_None);
1734 return Py_None;
1735#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001736 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001737 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001738 return NULL;
1739 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001740 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001741 Py_END_ALLOW_THREADS
1742 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001743 return posix_error_with_allocated_filename(path);
1744 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001745 Py_INCREF(Py_None);
1746 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001747#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001748}
1749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001750
Thomas Wouterscf297e42007-02-23 15:07:44 +00001751#ifdef HAVE_CHFLAGS
1752PyDoc_STRVAR(posix_chflags__doc__,
1753"chflags(path, flags)\n\n\
1754Set file flags.");
1755
1756static PyObject *
1757posix_chflags(PyObject *self, PyObject *args)
1758{
1759 char *path;
1760 unsigned long flags;
1761 int res;
1762 if (!PyArg_ParseTuple(args, "etk:chflags",
1763 Py_FileSystemDefaultEncoding, &path, &flags))
1764 return NULL;
1765 Py_BEGIN_ALLOW_THREADS
1766 res = chflags(path, flags);
1767 Py_END_ALLOW_THREADS
1768 if (res < 0)
1769 return posix_error_with_allocated_filename(path);
1770 PyMem_Free(path);
1771 Py_INCREF(Py_None);
1772 return Py_None;
1773}
1774#endif /* HAVE_CHFLAGS */
1775
1776#ifdef HAVE_LCHFLAGS
1777PyDoc_STRVAR(posix_lchflags__doc__,
1778"lchflags(path, flags)\n\n\
1779Set file flags.\n\
1780This function will not follow symbolic links.");
1781
1782static PyObject *
1783posix_lchflags(PyObject *self, PyObject *args)
1784{
1785 char *path;
1786 unsigned long flags;
1787 int res;
1788 if (!PyArg_ParseTuple(args, "etk:lchflags",
1789 Py_FileSystemDefaultEncoding, &path, &flags))
1790 return NULL;
1791 Py_BEGIN_ALLOW_THREADS
1792 res = lchflags(path, flags);
1793 Py_END_ALLOW_THREADS
1794 if (res < 0)
1795 return posix_error_with_allocated_filename(path);
1796 PyMem_Free(path);
1797 Py_INCREF(Py_None);
1798 return Py_None;
1799}
1800#endif /* HAVE_LCHFLAGS */
1801
Martin v. Löwis244edc82001-10-04 22:44:26 +00001802#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001803PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001804"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001805Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001806
1807static PyObject *
1808posix_chroot(PyObject *self, PyObject *args)
1809{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001810 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001811}
1812#endif
1813
Guido van Rossum21142a01999-01-08 21:05:37 +00001814#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001815PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001816"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001818
1819static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001820posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001821{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001822 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001823}
1824#endif /* HAVE_FSYNC */
1825
1826#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001827
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001828#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001829extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1830#endif
1831
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001832PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001833"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001834force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001835 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001836
1837static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001838posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001839{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001840 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001841}
1842#endif /* HAVE_FDATASYNC */
1843
1844
Fredrik Lundh10723342000-07-10 16:38:09 +00001845#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001846PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001847"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001848Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001849
Barry Warsaw53699e91996-12-10 23:23:01 +00001850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001851posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001852{
Mark Hammondef8b6542001-05-13 08:04:26 +00001853 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001854 int uid, gid;
1855 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001856 if (!PyArg_ParseTuple(args, "etii:chown",
1857 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001858 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001859 return NULL;
1860 Py_BEGIN_ALLOW_THREADS
1861 res = chown(path, (uid_t) uid, (gid_t) gid);
1862 Py_END_ALLOW_THREADS
1863 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001864 return posix_error_with_allocated_filename(path);
1865 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001866 Py_INCREF(Py_None);
1867 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001868}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001869#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001870
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001871#ifdef HAVE_LCHOWN
1872PyDoc_STRVAR(posix_lchown__doc__,
1873"lchown(path, uid, gid)\n\n\
1874Change the owner and group id of path to the numeric uid and gid.\n\
1875This function will not follow symbolic links.");
1876
1877static PyObject *
1878posix_lchown(PyObject *self, PyObject *args)
1879{
1880 char *path = NULL;
1881 int uid, gid;
1882 int res;
1883 if (!PyArg_ParseTuple(args, "etii:lchown",
1884 Py_FileSystemDefaultEncoding, &path,
1885 &uid, &gid))
1886 return NULL;
1887 Py_BEGIN_ALLOW_THREADS
1888 res = lchown(path, (uid_t) uid, (gid_t) gid);
1889 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001890 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001891 return posix_error_with_allocated_filename(path);
1892 PyMem_Free(path);
1893 Py_INCREF(Py_None);
1894 return Py_None;
1895}
1896#endif /* HAVE_LCHOWN */
1897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001898
Guido van Rossum36bc6801995-06-14 22:54:23 +00001899#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001900PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001901"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001902Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001903
Barry Warsaw53699e91996-12-10 23:23:01 +00001904static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001905posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001906{
1907 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001908 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001909
Barry Warsaw53699e91996-12-10 23:23:01 +00001910 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001911#if defined(PYOS_OS2) && defined(PYCC_GCC)
1912 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001913#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001914 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001915#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001916 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001917 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001918 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001919 return PyUnicode_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001920}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001921
1922PyDoc_STRVAR(posix_getcwdu__doc__,
1923"getcwdu() -> path\n\n\
1924Return a unicode string representing the current working directory.");
1925
1926static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001927posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001928{
1929 char buf[1026];
1930 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001931
1932#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001933 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001934 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001935 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001936 wchar_t *wbuf2 = wbuf;
1937 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001938 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001939 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1940 /* If the buffer is large enough, len does not include the
1941 terminating \0. If the buffer is too small, len includes
1942 the space needed for the terminator. */
1943 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1944 wbuf2 = malloc(len * sizeof(wchar_t));
1945 if (wbuf2)
1946 len = GetCurrentDirectoryW(len, wbuf2);
1947 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001948 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001949 if (!wbuf2) {
1950 PyErr_NoMemory();
1951 return NULL;
1952 }
1953 if (!len) {
1954 if (wbuf2 != wbuf) free(wbuf2);
1955 return win32_error("getcwdu", NULL);
1956 }
1957 resobj = PyUnicode_FromWideChar(wbuf2, len);
1958 if (wbuf2 != wbuf) free(wbuf2);
1959 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001960 }
1961#endif
1962
1963 Py_BEGIN_ALLOW_THREADS
1964#if defined(PYOS_OS2) && defined(PYCC_GCC)
1965 res = _getcwd2(buf, sizeof buf);
1966#else
1967 res = getcwd(buf, sizeof buf);
1968#endif
1969 Py_END_ALLOW_THREADS
1970 if (res == NULL)
1971 return posix_error();
1972 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1973}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001974#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001976
Guido van Rossumb6775db1994-08-01 11:34:53 +00001977#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001978PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001979"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001980Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001981
Barry Warsaw53699e91996-12-10 23:23:01 +00001982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001983posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001984{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001985 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001986}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001987#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001988
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001989
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001990PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001991"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001992Return a list containing the names of the entries in the directory.\n\
1993\n\
1994 path: path of directory to list\n\
1995\n\
1996The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001997entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001998
Barry Warsaw53699e91996-12-10 23:23:01 +00001999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002000posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002001{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002002 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002003 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002004#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002005
Barry Warsaw53699e91996-12-10 23:23:01 +00002006 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002007 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002008 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002009 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002010 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002011 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002012 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002013
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002014#ifdef Py_WIN_WIDE_FILENAMES
2015 /* If on wide-character-capable OS see if argument
2016 is Unicode and if so use wide API. */
2017 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002018 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002019 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2020 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002021 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002022 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002023 /* Overallocate for \\*.*\0 */
2024 len = PyUnicode_GET_SIZE(po);
2025 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2026 if (!wnamebuf) {
2027 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002028 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002029 }
2030 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2031 wch = len > 0 ? wnamebuf[len-1] : '\0';
2032 if (wch != L'/' && wch != L'\\' && wch != L':')
2033 wnamebuf[len++] = L'\\';
2034 wcscpy(wnamebuf + len, L"*.*");
2035 if ((d = PyList_New(0)) == NULL) {
2036 free(wnamebuf);
2037 return NULL;
2038 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002039 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2040 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002041 int error = GetLastError();
2042 if (error == ERROR_FILE_NOT_FOUND) {
2043 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002044 return d;
2045 }
2046 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002047 win32_error_unicode("FindFirstFileW", wnamebuf);
2048 free(wnamebuf);
2049 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002050 }
2051 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002052 /* Skip over . and .. */
2053 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2054 wcscmp(wFileData.cFileName, L"..") != 0) {
2055 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2056 if (v == NULL) {
2057 Py_DECREF(d);
2058 d = NULL;
2059 break;
2060 }
2061 if (PyList_Append(d, v) != 0) {
2062 Py_DECREF(v);
2063 Py_DECREF(d);
2064 d = NULL;
2065 break;
2066 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002067 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002068 }
Georg Brandl622927b2006-03-07 12:48:03 +00002069 Py_BEGIN_ALLOW_THREADS
2070 result = FindNextFileW(hFindFile, &wFileData);
2071 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002072 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2073 it got to the end of the directory. */
2074 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2075 Py_DECREF(d);
2076 win32_error_unicode("FindNextFileW", wnamebuf);
2077 FindClose(hFindFile);
2078 free(wnamebuf);
2079 return NULL;
2080 }
Georg Brandl622927b2006-03-07 12:48:03 +00002081 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002082
2083 if (FindClose(hFindFile) == FALSE) {
2084 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002085 win32_error_unicode("FindClose", wnamebuf);
2086 free(wnamebuf);
2087 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002088 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002089 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002090 return d;
2091 }
2092 /* Drop the argument parsing error as narrow strings
2093 are also valid. */
2094 PyErr_Clear();
2095 }
2096#endif
2097
Tim Peters5aa91602002-01-30 05:46:57 +00002098 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002099 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002100 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002101 if (len > 0) {
2102 char ch = namebuf[len-1];
2103 if (ch != SEP && ch != ALTSEP && ch != ':')
2104 namebuf[len++] = '/';
2105 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002106 strcpy(namebuf + len, "*.*");
2107
Barry Warsaw53699e91996-12-10 23:23:01 +00002108 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002109 return NULL;
2110
2111 hFindFile = FindFirstFile(namebuf, &FileData);
2112 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002113 int error = GetLastError();
2114 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002115 return d;
2116 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002117 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002118 }
2119 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002120 /* Skip over . and .. */
2121 if (strcmp(FileData.cFileName, ".") != 0 &&
2122 strcmp(FileData.cFileName, "..") != 0) {
2123 v = PyString_FromString(FileData.cFileName);
2124 if (v == NULL) {
2125 Py_DECREF(d);
2126 d = NULL;
2127 break;
2128 }
2129 if (PyList_Append(d, v) != 0) {
2130 Py_DECREF(v);
2131 Py_DECREF(d);
2132 d = NULL;
2133 break;
2134 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002135 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002136 }
Georg Brandl622927b2006-03-07 12:48:03 +00002137 Py_BEGIN_ALLOW_THREADS
2138 result = FindNextFile(hFindFile, &FileData);
2139 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002140 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2141 it got to the end of the directory. */
2142 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2143 Py_DECREF(d);
2144 win32_error("FindNextFile", namebuf);
2145 FindClose(hFindFile);
2146 return NULL;
2147 }
Georg Brandl622927b2006-03-07 12:48:03 +00002148 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002149
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002150 if (FindClose(hFindFile) == FALSE) {
2151 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002152 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002153 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002154
2155 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002156
Tim Peters0bb44a42000-09-15 07:44:49 +00002157#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002158
2159#ifndef MAX_PATH
2160#define MAX_PATH CCHMAXPATH
2161#endif
2162 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002163 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002164 PyObject *d, *v;
2165 char namebuf[MAX_PATH+5];
2166 HDIR hdir = 1;
2167 ULONG srchcnt = 1;
2168 FILEFINDBUF3 ep;
2169 APIRET rc;
2170
Alexandre Vassalotti70a23712007-10-14 02:05:51 +00002171 if (!PyArg_ParseTuple(args, "et#:listdir",
2172 Py_FileSystemDefaultEncoding, &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002173 return NULL;
2174 if (len >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00002175 PyMem_Free(name);
2176 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002177 return NULL;
2178 }
2179 strcpy(namebuf, name);
2180 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002181 if (*pt == ALTSEP)
2182 *pt = SEP;
2183 if (namebuf[len-1] != SEP)
2184 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002185 strcpy(namebuf + len, "*.*");
2186
Neal Norwitz6c913782007-10-14 03:23:09 +00002187 if ((d = PyList_New(0)) == NULL) {
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002188 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002189 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002190 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002191
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002192 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2193 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002194 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002195 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2196 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2197 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002198
2199 if (rc != NO_ERROR) {
2200 errno = ENOENT;
Neal Norwitz6c913782007-10-14 03:23:09 +00002201 return posix_error_with_allocated_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002202 }
2203
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002204 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002205 do {
2206 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002207 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002208 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002209
2210 strcpy(namebuf, ep.achName);
2211
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002212 /* Leave Case of Name Alone -- In Native Form */
2213 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002214
2215 v = PyString_FromString(namebuf);
2216 if (v == NULL) {
2217 Py_DECREF(d);
2218 d = NULL;
2219 break;
2220 }
2221 if (PyList_Append(d, v) != 0) {
2222 Py_DECREF(v);
2223 Py_DECREF(d);
2224 d = NULL;
2225 break;
2226 }
2227 Py_DECREF(v);
2228 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2229 }
2230
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002231 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002232 return d;
2233#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002234
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002235 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002236 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002237 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002238 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002239 int arg_is_unicode = 1;
2240
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002241 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002242 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2243 arg_is_unicode = 0;
2244 PyErr_Clear();
2245 }
2246 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002247 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002248 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002249 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002250 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002251 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002252 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002253 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002254 return NULL;
2255 }
Georg Brandl622927b2006-03-07 12:48:03 +00002256 for (;;) {
2257 Py_BEGIN_ALLOW_THREADS
2258 ep = readdir(dirp);
2259 Py_END_ALLOW_THREADS
2260 if (ep == NULL)
2261 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002262 if (ep->d_name[0] == '.' &&
2263 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002264 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002265 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002266 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002267 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002268 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002269 d = NULL;
2270 break;
2271 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002272 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002273 PyObject *w;
2274
2275 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002276 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002277 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002278 if (w != NULL) {
2279 Py_DECREF(v);
2280 v = w;
2281 }
2282 else {
2283 /* fall back to the original byte string, as
2284 discussed in patch #683592 */
2285 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002286 }
Just van Rossum46c97842003-02-25 21:42:15 +00002287 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002288 if (PyList_Append(d, v) != 0) {
2289 Py_DECREF(v);
2290 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002291 d = NULL;
2292 break;
2293 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002294 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002295 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002296 if (errno != 0 && d != NULL) {
2297 /* readdir() returned NULL and set errno */
2298 closedir(dirp);
2299 Py_DECREF(d);
2300 return posix_error_with_allocated_filename(name);
2301 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002302 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002303 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002304
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002305 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002306
Tim Peters0bb44a42000-09-15 07:44:49 +00002307#endif /* which OS */
2308} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002309
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002310#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002311/* A helper function for abspath on win32 */
2312static PyObject *
2313posix__getfullpathname(PyObject *self, PyObject *args)
2314{
2315 /* assume encoded strings wont more than double no of chars */
2316 char inbuf[MAX_PATH*2];
2317 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002318 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002319 char outbuf[MAX_PATH*2];
2320 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002321#ifdef Py_WIN_WIDE_FILENAMES
2322 if (unicode_file_names()) {
2323 PyUnicodeObject *po;
2324 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2325 Py_UNICODE woutbuf[MAX_PATH*2];
2326 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002327 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002328 sizeof(woutbuf)/sizeof(woutbuf[0]),
2329 woutbuf, &wtemp))
2330 return win32_error("GetFullPathName", "");
2331 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2332 }
2333 /* Drop the argument parsing error as narrow strings
2334 are also valid. */
2335 PyErr_Clear();
2336 }
2337#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002338 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2339 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002340 &insize))
2341 return NULL;
2342 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2343 outbuf, &temp))
2344 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002345 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2346 return PyUnicode_Decode(outbuf, strlen(outbuf),
2347 Py_FileSystemDefaultEncoding, NULL);
2348 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002349 return PyString_FromString(outbuf);
2350} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002351#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002352
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002353PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002354"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002355Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002356
Barry Warsaw53699e91996-12-10 23:23:01 +00002357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002358posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002359{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002360 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002361 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002362 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002363
2364#ifdef Py_WIN_WIDE_FILENAMES
2365 if (unicode_file_names()) {
2366 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002367 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002368 Py_BEGIN_ALLOW_THREADS
2369 /* PyUnicode_AS_UNICODE OK without thread lock as
2370 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002371 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002372 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002373 if (!res)
2374 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002375 Py_INCREF(Py_None);
2376 return Py_None;
2377 }
2378 /* Drop the argument parsing error as narrow strings
2379 are also valid. */
2380 PyErr_Clear();
2381 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002382 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2383 Py_FileSystemDefaultEncoding, &path, &mode))
2384 return NULL;
2385 Py_BEGIN_ALLOW_THREADS
2386 /* PyUnicode_AS_UNICODE OK without thread lock as
2387 it is a simple dereference. */
2388 res = CreateDirectoryA(path, NULL);
2389 Py_END_ALLOW_THREADS
2390 if (!res) {
2391 win32_error("mkdir", path);
2392 PyMem_Free(path);
2393 return NULL;
2394 }
2395 PyMem_Free(path);
2396 Py_INCREF(Py_None);
2397 return Py_None;
2398#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002399
Tim Peters5aa91602002-01-30 05:46:57 +00002400 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002401 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002402 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002403 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002404#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002405 res = mkdir(path);
2406#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002407 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002408#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002409 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002410 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002411 return posix_error_with_allocated_filename(path);
2412 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002413 Py_INCREF(Py_None);
2414 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002415#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002416}
2417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002418
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002419/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2420#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002421#include <sys/resource.h>
2422#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002423
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002424
2425#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002426PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002427"nice(inc) -> new_priority\n\n\
2428Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002429
Barry Warsaw53699e91996-12-10 23:23:01 +00002430static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002431posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002432{
2433 int increment, value;
2434
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002435 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002436 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002437
2438 /* There are two flavours of 'nice': one that returns the new
2439 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002440 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2441 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002442
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002443 If we are of the nice family that returns the new priority, we
2444 need to clear errno before the call, and check if errno is filled
2445 before calling posix_error() on a returnvalue of -1, because the
2446 -1 may be the actual new priority! */
2447
2448 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002449 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002450#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002451 if (value == 0)
2452 value = getpriority(PRIO_PROCESS, 0);
2453#endif
2454 if (value == -1 && errno != 0)
2455 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002456 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002457 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002458}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002459#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002460
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002461PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002462"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002463Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002464
Barry Warsaw53699e91996-12-10 23:23:01 +00002465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002466posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002467{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002468#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002469 PyObject *o1, *o2;
2470 char *p1, *p2;
2471 BOOL result;
2472 if (unicode_file_names()) {
2473 if (!PyArg_ParseTuple(args, "O&O&:rename",
2474 convert_to_unicode, &o1,
2475 convert_to_unicode, &o2))
2476 PyErr_Clear();
2477 else {
2478 Py_BEGIN_ALLOW_THREADS
2479 result = MoveFileW(PyUnicode_AsUnicode(o1),
2480 PyUnicode_AsUnicode(o2));
2481 Py_END_ALLOW_THREADS
2482 Py_DECREF(o1);
2483 Py_DECREF(o2);
2484 if (!result)
2485 return win32_error("rename", NULL);
2486 Py_INCREF(Py_None);
2487 return Py_None;
2488 }
2489 }
2490 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2491 return NULL;
2492 Py_BEGIN_ALLOW_THREADS
2493 result = MoveFileA(p1, p2);
2494 Py_END_ALLOW_THREADS
2495 if (!result)
2496 return win32_error("rename", NULL);
2497 Py_INCREF(Py_None);
2498 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002499#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002500 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002501#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002502}
2503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002505PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002506"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002507Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002508
Barry Warsaw53699e91996-12-10 23:23:01 +00002509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002510posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002511{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002512#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002513 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002514#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002515 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002516#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002517}
2518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002520PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002521"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002522Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002523
Barry Warsaw53699e91996-12-10 23:23:01 +00002524static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002525posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002526{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002527#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002528 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002529#else
2530 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2531#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002532}
2533
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002534
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002535#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002536PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002537"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002538Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002539
Barry Warsaw53699e91996-12-10 23:23:01 +00002540static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002541posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002542{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002543 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002544 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002545 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002546 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002547 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002548 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002549 Py_END_ALLOW_THREADS
2550 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002551}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002552#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002553
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002554
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002555PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002556"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002557Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002558
Barry Warsaw53699e91996-12-10 23:23:01 +00002559static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002560posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002561{
2562 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002563 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002564 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002565 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002566 if (i < 0)
2567 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002568 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002569}
2570
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002571
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002572PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002573"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002574Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002575
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002576PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002577"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002578Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002579
Barry Warsaw53699e91996-12-10 23:23:01 +00002580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002581posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002582{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002583#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002584 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002585#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002586 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002587#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002588}
2589
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002590
Guido van Rossumb6775db1994-08-01 11:34:53 +00002591#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002592PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002593"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002594Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002595
Barry Warsaw53699e91996-12-10 23:23:01 +00002596static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002597posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002598{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002599 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002600 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002601
Barry Warsaw53699e91996-12-10 23:23:01 +00002602 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002603 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002604 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002605 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002606 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002607 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002608 u.sysname,
2609 u.nodename,
2610 u.release,
2611 u.version,
2612 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002613}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002614#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002615
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002616static int
2617extract_time(PyObject *t, long* sec, long* usec)
2618{
2619 long intval;
2620 if (PyFloat_Check(t)) {
2621 double tval = PyFloat_AsDouble(t);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002622 PyObject *intobj = Py_Type(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002623 if (!intobj)
2624 return -1;
2625 intval = PyInt_AsLong(intobj);
2626 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002627 if (intval == -1 && PyErr_Occurred())
2628 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002629 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002630 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002631 if (*usec < 0)
2632 /* If rounding gave us a negative number,
2633 truncate. */
2634 *usec = 0;
2635 return 0;
2636 }
2637 intval = PyInt_AsLong(t);
2638 if (intval == -1 && PyErr_Occurred())
2639 return -1;
2640 *sec = intval;
2641 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002642 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002643}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002644
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002645PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002646"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002647utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002648Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002649second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002650
Barry Warsaw53699e91996-12-10 23:23:01 +00002651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002652posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002653{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002654#ifdef Py_WIN_WIDE_FILENAMES
2655 PyObject *arg;
2656 PyUnicodeObject *obwpath;
2657 wchar_t *wpath = NULL;
2658 char *apath = NULL;
2659 HANDLE hFile;
2660 long atimesec, mtimesec, ausec, musec;
2661 FILETIME atime, mtime;
2662 PyObject *result = NULL;
2663
2664 if (unicode_file_names()) {
2665 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2666 wpath = PyUnicode_AS_UNICODE(obwpath);
2667 Py_BEGIN_ALLOW_THREADS
2668 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002669 NULL, OPEN_EXISTING,
2670 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002671 Py_END_ALLOW_THREADS
2672 if (hFile == INVALID_HANDLE_VALUE)
2673 return win32_error_unicode("utime", wpath);
2674 } else
2675 /* Drop the argument parsing error as narrow strings
2676 are also valid. */
2677 PyErr_Clear();
2678 }
2679 if (!wpath) {
2680 if (!PyArg_ParseTuple(args, "etO:utime",
2681 Py_FileSystemDefaultEncoding, &apath, &arg))
2682 return NULL;
2683 Py_BEGIN_ALLOW_THREADS
2684 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002685 NULL, OPEN_EXISTING,
2686 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002687 Py_END_ALLOW_THREADS
2688 if (hFile == INVALID_HANDLE_VALUE) {
2689 win32_error("utime", apath);
2690 PyMem_Free(apath);
2691 return NULL;
2692 }
2693 PyMem_Free(apath);
2694 }
2695
2696 if (arg == Py_None) {
2697 SYSTEMTIME now;
2698 GetSystemTime(&now);
2699 if (!SystemTimeToFileTime(&now, &mtime) ||
2700 !SystemTimeToFileTime(&now, &atime)) {
2701 win32_error("utime", NULL);
2702 goto done;
2703 }
2704 }
2705 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2706 PyErr_SetString(PyExc_TypeError,
2707 "utime() arg 2 must be a tuple (atime, mtime)");
2708 goto done;
2709 }
2710 else {
2711 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2712 &atimesec, &ausec) == -1)
2713 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002714 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002715 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2716 &mtimesec, &musec) == -1)
2717 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002718 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002719 }
2720 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2721 /* Avoid putting the file name into the error here,
2722 as that may confuse the user into believing that
2723 something is wrong with the file, when it also
2724 could be the time stamp that gives a problem. */
2725 win32_error("utime", NULL);
2726 }
2727 Py_INCREF(Py_None);
2728 result = Py_None;
2729done:
2730 CloseHandle(hFile);
2731 return result;
2732#else /* Py_WIN_WIDE_FILENAMES */
2733
Neal Norwitz2adf2102004-06-09 01:46:02 +00002734 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002735 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002736 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002737 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002738
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002739#if defined(HAVE_UTIMES)
2740 struct timeval buf[2];
2741#define ATIME buf[0].tv_sec
2742#define MTIME buf[1].tv_sec
2743#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002744/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002745 struct utimbuf buf;
2746#define ATIME buf.actime
2747#define MTIME buf.modtime
2748#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002749#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002750 time_t buf[2];
2751#define ATIME buf[0]
2752#define MTIME buf[1]
2753#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002754#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002755
Mark Hammond817c9292003-12-03 01:22:38 +00002756
Thomas Wouters477c8d52006-05-27 19:21:47 +00002757 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002758 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002759 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002760 if (arg == Py_None) {
2761 /* optional time values not given */
2762 Py_BEGIN_ALLOW_THREADS
2763 res = utime(path, NULL);
2764 Py_END_ALLOW_THREADS
2765 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002766 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002767 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002768 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002769 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002770 return NULL;
2771 }
2772 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002773 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002774 &atime, &ausec) == -1) {
2775 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002776 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002777 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002778 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002779 &mtime, &musec) == -1) {
2780 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002781 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002782 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002783 ATIME = atime;
2784 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002785#ifdef HAVE_UTIMES
2786 buf[0].tv_usec = ausec;
2787 buf[1].tv_usec = musec;
2788 Py_BEGIN_ALLOW_THREADS
2789 res = utimes(path, buf);
2790 Py_END_ALLOW_THREADS
2791#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002792 Py_BEGIN_ALLOW_THREADS
2793 res = utime(path, UTIME_ARG);
2794 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002795#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002796 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002797 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002798 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002799 }
Neal Norwitz96652712004-06-06 20:40:27 +00002800 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002801 Py_INCREF(Py_None);
2802 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002803#undef UTIME_ARG
2804#undef ATIME
2805#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00002806#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002807}
2808
Guido van Rossum85e3b011991-06-03 12:42:10 +00002809
Guido van Rossum3b066191991-06-04 19:40:25 +00002810/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002811
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002812PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002813"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002814Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002815
Barry Warsaw53699e91996-12-10 23:23:01 +00002816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002817posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002818{
2819 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002820 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002821 return NULL;
2822 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002823 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002824}
2825
Martin v. Löwis114619e2002-10-07 06:44:21 +00002826#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2827static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002828free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002829{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002830 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002831 for (i = 0; i < count; i++)
2832 PyMem_Free(array[i]);
2833 PyMem_DEL(array);
2834}
2835#endif
2836
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002837
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002838#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002840"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002841Execute an executable path with arguments, replacing current process.\n\
2842\n\
2843 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002844 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002845
Barry Warsaw53699e91996-12-10 23:23:01 +00002846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002847posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002848{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002849 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002850 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002851 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002852 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002853 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002854
Guido van Rossum89b33251993-10-22 14:26:06 +00002855 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002856 argv is a list or tuple of strings. */
2857
Martin v. Löwis114619e2002-10-07 06:44:21 +00002858 if (!PyArg_ParseTuple(args, "etO:execv",
2859 Py_FileSystemDefaultEncoding,
2860 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002861 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002862 if (PyList_Check(argv)) {
2863 argc = PyList_Size(argv);
2864 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002865 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002866 else if (PyTuple_Check(argv)) {
2867 argc = PyTuple_Size(argv);
2868 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002869 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002870 else {
Fred Drake661ea262000-10-24 19:57:45 +00002871 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002872 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002873 return NULL;
2874 }
Thomas Heller6790d602007-08-30 17:15:14 +00002875 if (argc < 1) {
2876 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
2877 PyMem_Free(path);
2878 return NULL;
2879 }
Guido van Rossum50422b42000-04-26 20:34:28 +00002880
Barry Warsaw53699e91996-12-10 23:23:01 +00002881 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002882 if (argvlist == NULL) {
2883 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002884 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002885 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002886 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002887 if (!PyArg_Parse((*getitem)(argv, i), "et",
2888 Py_FileSystemDefaultEncoding,
2889 &argvlist[i])) {
2890 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002891 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002892 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002893 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002894 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002895
Guido van Rossum85e3b011991-06-03 12:42:10 +00002896 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002897 }
2898 argvlist[argc] = NULL;
2899
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002900 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002901
Guido van Rossum85e3b011991-06-03 12:42:10 +00002902 /* If we get here it's definitely an error */
2903
Martin v. Löwis114619e2002-10-07 06:44:21 +00002904 free_string_array(argvlist, argc);
2905 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002906 return posix_error();
2907}
2908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002909
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002910PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002911"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002912Execute a path with arguments and environment, replacing current process.\n\
2913\n\
2914 path: path of executable file\n\
2915 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002916 env: dictionary of strings mapping to strings");
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_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002920{
2921 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002922 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002923 char **argvlist;
2924 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002925 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002926 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002927 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002928 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002929
2930 /* execve has three arguments: (path, argv, env), where
2931 argv is a list or tuple of strings and env is a dictionary
2932 like posix.environ. */
2933
Martin v. Löwis114619e2002-10-07 06:44:21 +00002934 if (!PyArg_ParseTuple(args, "etOO:execve",
2935 Py_FileSystemDefaultEncoding,
2936 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002937 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002938 if (PyList_Check(argv)) {
2939 argc = PyList_Size(argv);
2940 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002941 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002942 else if (PyTuple_Check(argv)) {
2943 argc = PyTuple_Size(argv);
2944 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002945 }
2946 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002947 PyErr_SetString(PyExc_TypeError,
2948 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002949 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002950 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002951 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002952 PyErr_SetString(PyExc_TypeError,
2953 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002954 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002955 }
2956
Barry Warsaw53699e91996-12-10 23:23:01 +00002957 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002958 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002959 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002960 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002961 }
2962 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002963 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002964 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002965 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002966 &argvlist[i]))
2967 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002968 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002969 goto fail_1;
2970 }
2971 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002972 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002973 argvlist[argc] = NULL;
2974
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002975 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002976 if (i < 0)
2977 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002978 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002979 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002980 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002981 goto fail_1;
2982 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002983 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002984 keys = PyMapping_Keys(env);
2985 vals = PyMapping_Values(env);
2986 if (!keys || !vals)
2987 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002988 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2989 PyErr_SetString(PyExc_TypeError,
2990 "execve(): env.keys() or env.values() is not a list");
2991 goto fail_2;
2992 }
Tim Peters5aa91602002-01-30 05:46:57 +00002993
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002994 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002995 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002996 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002997
2998 key = PyList_GetItem(keys, pos);
2999 val = PyList_GetItem(vals, pos);
3000 if (!key || !val)
3001 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003002
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003003 if (!PyArg_Parse(
3004 key,
3005 "s;execve() arg 3 contains a non-string key",
3006 &k) ||
3007 !PyArg_Parse(
3008 val,
3009 "s;execve() arg 3 contains a non-string value",
3010 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003011 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003012 goto fail_2;
3013 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003014
3015#if defined(PYOS_OS2)
3016 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3017 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3018#endif
Tim Petersc8996f52001-12-03 20:41:00 +00003019 len = PyString_Size(key) + PyString_Size(val) + 2;
3020 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003021 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003022 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003023 goto fail_2;
3024 }
Tim Petersc8996f52001-12-03 20:41:00 +00003025 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003026 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003027#if defined(PYOS_OS2)
3028 }
3029#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003030 }
3031 envlist[envc] = 0;
3032
3033 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003034
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003035 /* If we get here it's definitely an error */
3036
3037 (void) posix_error();
3038
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003039 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003040 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003041 PyMem_DEL(envlist[envc]);
3042 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003043 fail_1:
3044 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003045 Py_XDECREF(vals);
3046 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003047 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003048 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003049 return NULL;
3050}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003051#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003052
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003053
Guido van Rossuma1065681999-01-25 23:20:23 +00003054#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003055PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003056"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003057Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003058\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003059 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003060 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003061 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003062
3063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003064posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003065{
3066 char *path;
3067 PyObject *argv;
3068 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003069 int mode, i;
3070 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003071 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003072 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003073
3074 /* spawnv has three arguments: (mode, path, argv), where
3075 argv is a list or tuple of strings. */
3076
Martin v. Löwis114619e2002-10-07 06:44:21 +00003077 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3078 Py_FileSystemDefaultEncoding,
3079 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003080 return NULL;
3081 if (PyList_Check(argv)) {
3082 argc = PyList_Size(argv);
3083 getitem = PyList_GetItem;
3084 }
3085 else if (PyTuple_Check(argv)) {
3086 argc = PyTuple_Size(argv);
3087 getitem = PyTuple_GetItem;
3088 }
3089 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003090 PyErr_SetString(PyExc_TypeError,
3091 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003092 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003093 return NULL;
3094 }
3095
3096 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003097 if (argvlist == NULL) {
3098 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003099 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003100 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003101 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003102 if (!PyArg_Parse((*getitem)(argv, i), "et",
3103 Py_FileSystemDefaultEncoding,
3104 &argvlist[i])) {
3105 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003106 PyErr_SetString(
3107 PyExc_TypeError,
3108 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003109 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003110 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003111 }
3112 }
3113 argvlist[argc] = NULL;
3114
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003115#if defined(PYOS_OS2) && defined(PYCC_GCC)
3116 Py_BEGIN_ALLOW_THREADS
3117 spawnval = spawnv(mode, path, argvlist);
3118 Py_END_ALLOW_THREADS
3119#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003120 if (mode == _OLD_P_OVERLAY)
3121 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003122
Tim Peters25059d32001-12-07 20:35:43 +00003123 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003124 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003125 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003126#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003127
Martin v. Löwis114619e2002-10-07 06:44:21 +00003128 free_string_array(argvlist, argc);
3129 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003130
Fred Drake699f3522000-06-29 21:12:41 +00003131 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003132 return posix_error();
3133 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003134#if SIZEOF_LONG == SIZEOF_VOID_P
3135 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003136#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003137 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003138#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003139}
3140
3141
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003142PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003143"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003144Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003145\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003146 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003147 path: path of executable file\n\
3148 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003149 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003150
3151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003152posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003153{
3154 char *path;
3155 PyObject *argv, *env;
3156 char **argvlist;
3157 char **envlist;
3158 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003159 int mode, pos, envc;
3160 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003161 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003162 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003163 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003164
3165 /* spawnve has four arguments: (mode, path, argv, env), where
3166 argv is a list or tuple of strings and env is a dictionary
3167 like posix.environ. */
3168
Martin v. Löwis114619e2002-10-07 06:44:21 +00003169 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3170 Py_FileSystemDefaultEncoding,
3171 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003172 return NULL;
3173 if (PyList_Check(argv)) {
3174 argc = PyList_Size(argv);
3175 getitem = PyList_GetItem;
3176 }
3177 else if (PyTuple_Check(argv)) {
3178 argc = PyTuple_Size(argv);
3179 getitem = PyTuple_GetItem;
3180 }
3181 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003182 PyErr_SetString(PyExc_TypeError,
3183 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003184 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003185 }
3186 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003187 PyErr_SetString(PyExc_TypeError,
3188 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003189 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003190 }
3191
3192 argvlist = PyMem_NEW(char *, argc+1);
3193 if (argvlist == NULL) {
3194 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003195 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003196 }
3197 for (i = 0; i < argc; i++) {
3198 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003199 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003200 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003201 &argvlist[i]))
3202 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003203 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003204 goto fail_1;
3205 }
3206 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003207 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003208 argvlist[argc] = NULL;
3209
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003210 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003211 if (i < 0)
3212 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003213 envlist = PyMem_NEW(char *, i + 1);
3214 if (envlist == NULL) {
3215 PyErr_NoMemory();
3216 goto fail_1;
3217 }
3218 envc = 0;
3219 keys = PyMapping_Keys(env);
3220 vals = PyMapping_Values(env);
3221 if (!keys || !vals)
3222 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003223 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3224 PyErr_SetString(PyExc_TypeError,
3225 "spawnve(): env.keys() or env.values() is not a list");
3226 goto fail_2;
3227 }
Tim Peters5aa91602002-01-30 05:46:57 +00003228
Guido van Rossuma1065681999-01-25 23:20:23 +00003229 for (pos = 0; pos < i; pos++) {
3230 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003231 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003232
3233 key = PyList_GetItem(keys, pos);
3234 val = PyList_GetItem(vals, pos);
3235 if (!key || !val)
3236 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003237
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003238 if (!PyArg_Parse(
3239 key,
3240 "s;spawnve() arg 3 contains a non-string key",
3241 &k) ||
3242 !PyArg_Parse(
3243 val,
3244 "s;spawnve() arg 3 contains a non-string value",
3245 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003246 {
3247 goto fail_2;
3248 }
Tim Petersc8996f52001-12-03 20:41:00 +00003249 len = PyString_Size(key) + PyString_Size(val) + 2;
3250 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003251 if (p == NULL) {
3252 PyErr_NoMemory();
3253 goto fail_2;
3254 }
Tim Petersc8996f52001-12-03 20:41:00 +00003255 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003256 envlist[envc++] = p;
3257 }
3258 envlist[envc] = 0;
3259
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003260#if defined(PYOS_OS2) && defined(PYCC_GCC)
3261 Py_BEGIN_ALLOW_THREADS
3262 spawnval = spawnve(mode, path, argvlist, envlist);
3263 Py_END_ALLOW_THREADS
3264#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003265 if (mode == _OLD_P_OVERLAY)
3266 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003267
3268 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003269 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003270 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003271#endif
Tim Peters25059d32001-12-07 20:35:43 +00003272
Fred Drake699f3522000-06-29 21:12:41 +00003273 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003274 (void) posix_error();
3275 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003276#if SIZEOF_LONG == SIZEOF_VOID_P
3277 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003278#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003279 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003280#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003281
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003282 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003283 while (--envc >= 0)
3284 PyMem_DEL(envlist[envc]);
3285 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003286 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003287 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003288 Py_XDECREF(vals);
3289 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003290 fail_0:
3291 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003292 return res;
3293}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003294
3295/* OS/2 supports spawnvp & spawnvpe natively */
3296#if defined(PYOS_OS2)
3297PyDoc_STRVAR(posix_spawnvp__doc__,
3298"spawnvp(mode, file, args)\n\n\
3299Execute the program 'file' in a new process, using the environment\n\
3300search path to find the file.\n\
3301\n\
3302 mode: mode of process creation\n\
3303 file: executable file name\n\
3304 args: tuple or list of strings");
3305
3306static PyObject *
3307posix_spawnvp(PyObject *self, PyObject *args)
3308{
3309 char *path;
3310 PyObject *argv;
3311 char **argvlist;
3312 int mode, i, argc;
3313 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003314 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003315
3316 /* spawnvp has three arguments: (mode, path, argv), where
3317 argv is a list or tuple of strings. */
3318
3319 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3320 Py_FileSystemDefaultEncoding,
3321 &path, &argv))
3322 return NULL;
3323 if (PyList_Check(argv)) {
3324 argc = PyList_Size(argv);
3325 getitem = PyList_GetItem;
3326 }
3327 else if (PyTuple_Check(argv)) {
3328 argc = PyTuple_Size(argv);
3329 getitem = PyTuple_GetItem;
3330 }
3331 else {
3332 PyErr_SetString(PyExc_TypeError,
3333 "spawnvp() arg 2 must be a tuple or list");
3334 PyMem_Free(path);
3335 return NULL;
3336 }
3337
3338 argvlist = PyMem_NEW(char *, argc+1);
3339 if (argvlist == NULL) {
3340 PyMem_Free(path);
3341 return PyErr_NoMemory();
3342 }
3343 for (i = 0; i < argc; i++) {
3344 if (!PyArg_Parse((*getitem)(argv, i), "et",
3345 Py_FileSystemDefaultEncoding,
3346 &argvlist[i])) {
3347 free_string_array(argvlist, i);
3348 PyErr_SetString(
3349 PyExc_TypeError,
3350 "spawnvp() arg 2 must contain only strings");
3351 PyMem_Free(path);
3352 return NULL;
3353 }
3354 }
3355 argvlist[argc] = NULL;
3356
3357 Py_BEGIN_ALLOW_THREADS
3358#if defined(PYCC_GCC)
3359 spawnval = spawnvp(mode, path, argvlist);
3360#else
3361 spawnval = _spawnvp(mode, path, argvlist);
3362#endif
3363 Py_END_ALLOW_THREADS
3364
3365 free_string_array(argvlist, argc);
3366 PyMem_Free(path);
3367
3368 if (spawnval == -1)
3369 return posix_error();
3370 else
3371 return Py_BuildValue("l", (long) spawnval);
3372}
3373
3374
3375PyDoc_STRVAR(posix_spawnvpe__doc__,
3376"spawnvpe(mode, file, args, env)\n\n\
3377Execute the program 'file' in a new process, using the environment\n\
3378search path to find the file.\n\
3379\n\
3380 mode: mode of process creation\n\
3381 file: executable file name\n\
3382 args: tuple or list of arguments\n\
3383 env: dictionary of strings mapping to strings");
3384
3385static PyObject *
3386posix_spawnvpe(PyObject *self, PyObject *args)
3387{
3388 char *path;
3389 PyObject *argv, *env;
3390 char **argvlist;
3391 char **envlist;
3392 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3393 int mode, i, pos, argc, envc;
3394 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003395 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003396 int lastarg = 0;
3397
3398 /* spawnvpe has four arguments: (mode, path, argv, env), where
3399 argv is a list or tuple of strings and env is a dictionary
3400 like posix.environ. */
3401
3402 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3403 Py_FileSystemDefaultEncoding,
3404 &path, &argv, &env))
3405 return NULL;
3406 if (PyList_Check(argv)) {
3407 argc = PyList_Size(argv);
3408 getitem = PyList_GetItem;
3409 }
3410 else if (PyTuple_Check(argv)) {
3411 argc = PyTuple_Size(argv);
3412 getitem = PyTuple_GetItem;
3413 }
3414 else {
3415 PyErr_SetString(PyExc_TypeError,
3416 "spawnvpe() arg 2 must be a tuple or list");
3417 goto fail_0;
3418 }
3419 if (!PyMapping_Check(env)) {
3420 PyErr_SetString(PyExc_TypeError,
3421 "spawnvpe() arg 3 must be a mapping object");
3422 goto fail_0;
3423 }
3424
3425 argvlist = PyMem_NEW(char *, argc+1);
3426 if (argvlist == NULL) {
3427 PyErr_NoMemory();
3428 goto fail_0;
3429 }
3430 for (i = 0; i < argc; i++) {
3431 if (!PyArg_Parse((*getitem)(argv, i),
3432 "et;spawnvpe() arg 2 must contain only strings",
3433 Py_FileSystemDefaultEncoding,
3434 &argvlist[i]))
3435 {
3436 lastarg = i;
3437 goto fail_1;
3438 }
3439 }
3440 lastarg = argc;
3441 argvlist[argc] = NULL;
3442
3443 i = PyMapping_Size(env);
3444 if (i < 0)
3445 goto fail_1;
3446 envlist = PyMem_NEW(char *, i + 1);
3447 if (envlist == NULL) {
3448 PyErr_NoMemory();
3449 goto fail_1;
3450 }
3451 envc = 0;
3452 keys = PyMapping_Keys(env);
3453 vals = PyMapping_Values(env);
3454 if (!keys || !vals)
3455 goto fail_2;
3456 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3457 PyErr_SetString(PyExc_TypeError,
3458 "spawnvpe(): env.keys() or env.values() is not a list");
3459 goto fail_2;
3460 }
3461
3462 for (pos = 0; pos < i; pos++) {
3463 char *p, *k, *v;
3464 size_t len;
3465
3466 key = PyList_GetItem(keys, pos);
3467 val = PyList_GetItem(vals, pos);
3468 if (!key || !val)
3469 goto fail_2;
3470
3471 if (!PyArg_Parse(
3472 key,
3473 "s;spawnvpe() arg 3 contains a non-string key",
3474 &k) ||
3475 !PyArg_Parse(
3476 val,
3477 "s;spawnvpe() arg 3 contains a non-string value",
3478 &v))
3479 {
3480 goto fail_2;
3481 }
3482 len = PyString_Size(key) + PyString_Size(val) + 2;
3483 p = PyMem_NEW(char, len);
3484 if (p == NULL) {
3485 PyErr_NoMemory();
3486 goto fail_2;
3487 }
3488 PyOS_snprintf(p, len, "%s=%s", k, v);
3489 envlist[envc++] = p;
3490 }
3491 envlist[envc] = 0;
3492
3493 Py_BEGIN_ALLOW_THREADS
3494#if defined(PYCC_GCC)
3495 spawnval = spawnve(mode, path, argvlist, envlist);
3496#else
3497 spawnval = _spawnve(mode, path, argvlist, envlist);
3498#endif
3499 Py_END_ALLOW_THREADS
3500
3501 if (spawnval == -1)
3502 (void) posix_error();
3503 else
3504 res = Py_BuildValue("l", (long) spawnval);
3505
3506 fail_2:
3507 while (--envc >= 0)
3508 PyMem_DEL(envlist[envc]);
3509 PyMem_DEL(envlist);
3510 fail_1:
3511 free_string_array(argvlist, lastarg);
3512 Py_XDECREF(vals);
3513 Py_XDECREF(keys);
3514 fail_0:
3515 PyMem_Free(path);
3516 return res;
3517}
3518#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003519#endif /* HAVE_SPAWNV */
3520
3521
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003522#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003523PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003524"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003525Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3526\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003527Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003528
3529static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003530posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003531{
Neal Norwitze241ce82003-02-17 18:17:05 +00003532 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003533 if (pid == -1)
3534 return posix_error();
3535 PyOS_AfterFork();
3536 return PyInt_FromLong((long)pid);
3537}
3538#endif
3539
3540
Guido van Rossumad0ee831995-03-01 10:34:45 +00003541#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003542PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003543"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003544Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003545Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003546
Barry Warsaw53699e91996-12-10 23:23:01 +00003547static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003548posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003549{
Neal Norwitze241ce82003-02-17 18:17:05 +00003550 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003551 if (pid == -1)
3552 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003553 if (pid == 0)
3554 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003555 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003556}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003557#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003558
Neal Norwitzb59798b2003-03-21 01:43:31 +00003559/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003560/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3561#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003562#define DEV_PTY_FILE "/dev/ptc"
3563#define HAVE_DEV_PTMX
3564#else
3565#define DEV_PTY_FILE "/dev/ptmx"
3566#endif
3567
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003568#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003569#ifdef HAVE_PTY_H
3570#include <pty.h>
3571#else
3572#ifdef HAVE_LIBUTIL_H
3573#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003574#endif /* HAVE_LIBUTIL_H */
3575#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003576#ifdef HAVE_STROPTS_H
3577#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003578#endif
3579#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003580
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003581#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003582PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003583"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003584Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003585
3586static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003587posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003588{
3589 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003590#ifndef HAVE_OPENPTY
3591 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003592#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003593#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003594 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003595#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003596 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003597#endif
3598#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003599
Thomas Wouters70c21a12000-07-14 14:28:33 +00003600#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003601 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3602 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003603#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003604 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3605 if (slave_name == NULL)
3606 return posix_error();
3607
3608 slave_fd = open(slave_name, O_RDWR);
3609 if (slave_fd < 0)
3610 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003611#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003612 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003613 if (master_fd < 0)
3614 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003615 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003616 /* change permission of slave */
3617 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003618 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003619 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003620 }
3621 /* unlock slave */
3622 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003623 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003624 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003625 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003626 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003627 slave_name = ptsname(master_fd); /* get name of slave */
3628 if (slave_name == NULL)
3629 return posix_error();
3630 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3631 if (slave_fd < 0)
3632 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003633#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003634 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3635 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003636#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003637 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003638#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003639#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003640#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003641
Fred Drake8cef4cf2000-06-28 16:40:38 +00003642 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003643
Fred Drake8cef4cf2000-06-28 16:40:38 +00003644}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003645#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003646
3647#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003648PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003649"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003650Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3651Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003652To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003653
3654static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003655posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003656{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003657 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003658
Fred Drake8cef4cf2000-06-28 16:40:38 +00003659 pid = forkpty(&master_fd, NULL, NULL, NULL);
3660 if (pid == -1)
3661 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003662 if (pid == 0)
3663 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003664 return Py_BuildValue("(ii)", pid, master_fd);
3665}
3666#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003667
Guido van Rossumad0ee831995-03-01 10:34:45 +00003668#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003669PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003670"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003671Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003672
Barry Warsaw53699e91996-12-10 23:23:01 +00003673static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003674posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003675{
Barry Warsaw53699e91996-12-10 23:23:01 +00003676 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003677}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003678#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003680
Guido van Rossumad0ee831995-03-01 10:34:45 +00003681#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003682PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003683"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003684Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003685
Barry Warsaw53699e91996-12-10 23:23:01 +00003686static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003687posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003688{
Barry Warsaw53699e91996-12-10 23:23:01 +00003689 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003690}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003691#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003692
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003693
Guido van Rossumad0ee831995-03-01 10:34:45 +00003694#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003695PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003696"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003697Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003698
Barry Warsaw53699e91996-12-10 23:23:01 +00003699static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003700posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003701{
Barry Warsaw53699e91996-12-10 23:23:01 +00003702 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003703}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003704#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003705
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003706
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003707PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003708"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003709Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003710
Barry Warsaw53699e91996-12-10 23:23:01 +00003711static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003712posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003713{
Barry Warsaw53699e91996-12-10 23:23:01 +00003714 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003715}
3716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003717
Fred Drakec9680921999-12-13 16:37:25 +00003718#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003719PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003720"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003721Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003722
3723static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003724posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003725{
3726 PyObject *result = NULL;
3727
Fred Drakec9680921999-12-13 16:37:25 +00003728#ifdef NGROUPS_MAX
3729#define MAX_GROUPS NGROUPS_MAX
3730#else
3731 /* defined to be 16 on Solaris7, so this should be a small number */
3732#define MAX_GROUPS 64
3733#endif
3734 gid_t grouplist[MAX_GROUPS];
3735 int n;
3736
3737 n = getgroups(MAX_GROUPS, grouplist);
3738 if (n < 0)
3739 posix_error();
3740 else {
3741 result = PyList_New(n);
3742 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003743 int i;
3744 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003745 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003746 if (o == NULL) {
3747 Py_DECREF(result);
3748 result = NULL;
3749 break;
3750 }
3751 PyList_SET_ITEM(result, i, o);
3752 }
3753 }
3754 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003755
Fred Drakec9680921999-12-13 16:37:25 +00003756 return result;
3757}
3758#endif
3759
Martin v. Löwis606edc12002-06-13 21:09:11 +00003760#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003761PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003762"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003763Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003764
3765static PyObject *
3766posix_getpgid(PyObject *self, PyObject *args)
3767{
3768 int pid, pgid;
3769 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3770 return NULL;
3771 pgid = getpgid(pid);
3772 if (pgid < 0)
3773 return posix_error();
3774 return PyInt_FromLong((long)pgid);
3775}
3776#endif /* HAVE_GETPGID */
3777
3778
Guido van Rossumb6775db1994-08-01 11:34:53 +00003779#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003780PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003781"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003782Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003783
Barry Warsaw53699e91996-12-10 23:23:01 +00003784static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003785posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003786{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003787#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003788 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003789#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003790 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003791#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003792}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003793#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003795
Guido van Rossumb6775db1994-08-01 11:34:53 +00003796#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003797PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003798"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003799Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003800
Barry Warsaw53699e91996-12-10 23:23:01 +00003801static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003802posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003803{
Guido van Rossum64933891994-10-20 21:56:42 +00003804#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003805 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003806#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003807 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003808#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003809 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003810 Py_INCREF(Py_None);
3811 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003812}
3813
Guido van Rossumb6775db1994-08-01 11:34:53 +00003814#endif /* HAVE_SETPGRP */
3815
Guido van Rossumad0ee831995-03-01 10:34:45 +00003816#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003817PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003818"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003819Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003820
Barry Warsaw53699e91996-12-10 23:23:01 +00003821static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003822posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003823{
Barry Warsaw53699e91996-12-10 23:23:01 +00003824 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003825}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003826#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003828
Fred Drake12c6e2d1999-12-14 21:25:03 +00003829#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003830PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003831"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003832Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003833
3834static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003835posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003836{
Neal Norwitze241ce82003-02-17 18:17:05 +00003837 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003838 char *name;
3839 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003840
Fred Drakea30680b2000-12-06 21:24:28 +00003841 errno = 0;
3842 name = getlogin();
3843 if (name == NULL) {
3844 if (errno)
3845 posix_error();
3846 else
3847 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003848 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003849 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003850 else
Neal Norwitz93c56822007-08-26 07:10:06 +00003851 result = PyUnicode_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003852 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003853
Fred Drake12c6e2d1999-12-14 21:25:03 +00003854 return result;
3855}
3856#endif
3857
Guido van Rossumad0ee831995-03-01 10:34:45 +00003858#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003859PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003860"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003861Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003862
Barry Warsaw53699e91996-12-10 23:23:01 +00003863static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003864posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003865{
Barry Warsaw53699e91996-12-10 23:23:01 +00003866 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003867}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003868#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003869
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003870
Guido van Rossumad0ee831995-03-01 10:34:45 +00003871#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003872PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003873"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003874Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003875
Barry Warsaw53699e91996-12-10 23:23:01 +00003876static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003877posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003878{
3879 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003880 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003881 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003882#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003883 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3884 APIRET rc;
3885 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003886 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003887
3888 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3889 APIRET rc;
3890 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003891 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003892
3893 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003894 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003895#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003896 if (kill(pid, sig) == -1)
3897 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003898#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003899 Py_INCREF(Py_None);
3900 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003901}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003902#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003903
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003904#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003905PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003906"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003907Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003908
3909static PyObject *
3910posix_killpg(PyObject *self, PyObject *args)
3911{
3912 int pgid, sig;
3913 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3914 return NULL;
3915 if (killpg(pgid, sig) == -1)
3916 return posix_error();
3917 Py_INCREF(Py_None);
3918 return Py_None;
3919}
3920#endif
3921
Guido van Rossumc0125471996-06-28 18:55:32 +00003922#ifdef HAVE_PLOCK
3923
3924#ifdef HAVE_SYS_LOCK_H
3925#include <sys/lock.h>
3926#endif
3927
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003928PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003929"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003930Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003931
Barry Warsaw53699e91996-12-10 23:23:01 +00003932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003933posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003934{
3935 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003936 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003937 return NULL;
3938 if (plock(op) == -1)
3939 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003940 Py_INCREF(Py_None);
3941 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003942}
3943#endif
3944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003945
Guido van Rossum3b066191991-06-04 19:40:25 +00003946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003947
Guido van Rossumb6775db1994-08-01 11:34:53 +00003948#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003949PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003950"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003951Set the current process's user id.");
3952
Barry Warsaw53699e91996-12-10 23:23:01 +00003953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003954posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003955{
3956 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003957 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003958 return NULL;
3959 if (setuid(uid) < 0)
3960 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003961 Py_INCREF(Py_None);
3962 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003963}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003964#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003966
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003967#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003968PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003969"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003970Set the current process's effective user id.");
3971
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003972static PyObject *
3973posix_seteuid (PyObject *self, PyObject *args)
3974{
3975 int euid;
3976 if (!PyArg_ParseTuple(args, "i", &euid)) {
3977 return NULL;
3978 } else if (seteuid(euid) < 0) {
3979 return posix_error();
3980 } else {
3981 Py_INCREF(Py_None);
3982 return Py_None;
3983 }
3984}
3985#endif /* HAVE_SETEUID */
3986
3987#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003988PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003989"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003990Set the current process's effective group id.");
3991
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003992static PyObject *
3993posix_setegid (PyObject *self, PyObject *args)
3994{
3995 int egid;
3996 if (!PyArg_ParseTuple(args, "i", &egid)) {
3997 return NULL;
3998 } else if (setegid(egid) < 0) {
3999 return posix_error();
4000 } else {
4001 Py_INCREF(Py_None);
4002 return Py_None;
4003 }
4004}
4005#endif /* HAVE_SETEGID */
4006
4007#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004008PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004009"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004010Set the current process's real and effective user ids.");
4011
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004012static PyObject *
4013posix_setreuid (PyObject *self, PyObject *args)
4014{
4015 int ruid, euid;
4016 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4017 return NULL;
4018 } else if (setreuid(ruid, euid) < 0) {
4019 return posix_error();
4020 } else {
4021 Py_INCREF(Py_None);
4022 return Py_None;
4023 }
4024}
4025#endif /* HAVE_SETREUID */
4026
4027#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004028PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004029"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004030Set the current process's real and effective group ids.");
4031
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004032static PyObject *
4033posix_setregid (PyObject *self, PyObject *args)
4034{
4035 int rgid, egid;
4036 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4037 return NULL;
4038 } else if (setregid(rgid, egid) < 0) {
4039 return posix_error();
4040 } else {
4041 Py_INCREF(Py_None);
4042 return Py_None;
4043 }
4044}
4045#endif /* HAVE_SETREGID */
4046
Guido van Rossumb6775db1994-08-01 11:34:53 +00004047#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004048PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004049"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004050Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004051
Barry Warsaw53699e91996-12-10 23:23:01 +00004052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004053posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004054{
4055 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004056 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004057 return NULL;
4058 if (setgid(gid) < 0)
4059 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004060 Py_INCREF(Py_None);
4061 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004062}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004063#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004064
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004065#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004066PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004067"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004068Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004069
4070static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004071posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004072{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004073 int i, len;
4074 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004075
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004076 if (!PySequence_Check(groups)) {
4077 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4078 return NULL;
4079 }
4080 len = PySequence_Size(groups);
4081 if (len > MAX_GROUPS) {
4082 PyErr_SetString(PyExc_ValueError, "too many groups");
4083 return NULL;
4084 }
4085 for(i = 0; i < len; i++) {
4086 PyObject *elem;
4087 elem = PySequence_GetItem(groups, i);
4088 if (!elem)
4089 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004090 if (!PyLong_Check(elem)) {
4091 PyErr_SetString(PyExc_TypeError,
4092 "groups must be integers");
4093 Py_DECREF(elem);
4094 return NULL;
4095 } else {
4096 unsigned long x = PyLong_AsUnsignedLong(elem);
4097 if (PyErr_Occurred()) {
4098 PyErr_SetString(PyExc_TypeError,
4099 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004100 Py_DECREF(elem);
4101 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004102 }
Georg Brandla13c2442005-11-22 19:30:31 +00004103 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004104 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004105 if (grouplist[i] != x) {
4106 PyErr_SetString(PyExc_TypeError,
4107 "group id too big");
4108 Py_DECREF(elem);
4109 return NULL;
4110 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004111 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004112 Py_DECREF(elem);
4113 }
4114
4115 if (setgroups(len, grouplist) < 0)
4116 return posix_error();
4117 Py_INCREF(Py_None);
4118 return Py_None;
4119}
4120#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004121
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004122#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4123static PyObject *
4124wait_helper(int pid, int status, struct rusage *ru)
4125{
4126 PyObject *result;
4127 static PyObject *struct_rusage;
4128
4129 if (pid == -1)
4130 return posix_error();
4131
4132 if (struct_rusage == NULL) {
4133 PyObject *m = PyImport_ImportModule("resource");
4134 if (m == NULL)
4135 return NULL;
4136 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4137 Py_DECREF(m);
4138 if (struct_rusage == NULL)
4139 return NULL;
4140 }
4141
4142 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4143 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4144 if (!result)
4145 return NULL;
4146
4147#ifndef doubletime
4148#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4149#endif
4150
4151 PyStructSequence_SET_ITEM(result, 0,
4152 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4153 PyStructSequence_SET_ITEM(result, 1,
4154 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4155#define SET_INT(result, index, value)\
4156 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
4157 SET_INT(result, 2, ru->ru_maxrss);
4158 SET_INT(result, 3, ru->ru_ixrss);
4159 SET_INT(result, 4, ru->ru_idrss);
4160 SET_INT(result, 5, ru->ru_isrss);
4161 SET_INT(result, 6, ru->ru_minflt);
4162 SET_INT(result, 7, ru->ru_majflt);
4163 SET_INT(result, 8, ru->ru_nswap);
4164 SET_INT(result, 9, ru->ru_inblock);
4165 SET_INT(result, 10, ru->ru_oublock);
4166 SET_INT(result, 11, ru->ru_msgsnd);
4167 SET_INT(result, 12, ru->ru_msgrcv);
4168 SET_INT(result, 13, ru->ru_nsignals);
4169 SET_INT(result, 14, ru->ru_nvcsw);
4170 SET_INT(result, 15, ru->ru_nivcsw);
4171#undef SET_INT
4172
4173 if (PyErr_Occurred()) {
4174 Py_DECREF(result);
4175 return NULL;
4176 }
4177
4178 return Py_BuildValue("iiN", pid, status, result);
4179}
4180#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4181
4182#ifdef HAVE_WAIT3
4183PyDoc_STRVAR(posix_wait3__doc__,
4184"wait3(options) -> (pid, status, rusage)\n\n\
4185Wait for completion of a child process.");
4186
4187static PyObject *
4188posix_wait3(PyObject *self, PyObject *args)
4189{
4190 int pid, options;
4191 struct rusage ru;
4192 WAIT_TYPE status;
4193 WAIT_STATUS_INT(status) = 0;
4194
4195 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4196 return NULL;
4197
4198 Py_BEGIN_ALLOW_THREADS
4199 pid = wait3(&status, options, &ru);
4200 Py_END_ALLOW_THREADS
4201
4202 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4203}
4204#endif /* HAVE_WAIT3 */
4205
4206#ifdef HAVE_WAIT4
4207PyDoc_STRVAR(posix_wait4__doc__,
4208"wait4(pid, options) -> (pid, status, rusage)\n\n\
4209Wait for completion of a given child process.");
4210
4211static PyObject *
4212posix_wait4(PyObject *self, PyObject *args)
4213{
4214 int pid, options;
4215 struct rusage ru;
4216 WAIT_TYPE status;
4217 WAIT_STATUS_INT(status) = 0;
4218
4219 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
4220 return NULL;
4221
4222 Py_BEGIN_ALLOW_THREADS
4223 pid = wait4(pid, &status, options, &ru);
4224 Py_END_ALLOW_THREADS
4225
4226 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4227}
4228#endif /* HAVE_WAIT4 */
4229
Guido van Rossumb6775db1994-08-01 11:34:53 +00004230#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004231PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004232"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004233Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004234
Barry Warsaw53699e91996-12-10 23:23:01 +00004235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004236posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004237{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004238 int pid, options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004239 WAIT_TYPE status;
4240 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004241
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004242 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004243 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004244 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004245 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004246 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004247 if (pid == -1)
4248 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004249
4250 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004251}
4252
Tim Petersab034fa2002-02-01 11:27:43 +00004253#elif defined(HAVE_CWAIT)
4254
4255/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004256PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004257"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004258"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004259
4260static PyObject *
4261posix_waitpid(PyObject *self, PyObject *args)
4262{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004263 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004264 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004265
4266 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4267 return NULL;
4268 Py_BEGIN_ALLOW_THREADS
4269 pid = _cwait(&status, pid, options);
4270 Py_END_ALLOW_THREADS
4271 if (pid == -1)
4272 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004273
4274 /* shift the status left a byte so this is more like the POSIX waitpid */
4275 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004276}
4277#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004278
Guido van Rossumad0ee831995-03-01 10:34:45 +00004279#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004280PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004281"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004282Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004283
Barry Warsaw53699e91996-12-10 23:23:01 +00004284static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004285posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004286{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004287 int pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004288 WAIT_TYPE status;
4289 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004290
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004291 Py_BEGIN_ALLOW_THREADS
4292 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004293 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004294 if (pid == -1)
4295 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004296
4297 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004298}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004299#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004301
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004302PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004303"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004304Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004305
Barry Warsaw53699e91996-12-10 23:23:01 +00004306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004307posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004308{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004309#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004310 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004311#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004312#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00004313 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004314#else
4315 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4316#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004317#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004318}
4319
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004320
Guido van Rossumb6775db1994-08-01 11:34:53 +00004321#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004322PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004323"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004324Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004325
Barry Warsaw53699e91996-12-10 23:23:01 +00004326static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004327posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004328{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004329 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004330 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004331 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004332 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004333 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004334
4335 if (!PyArg_ParseTuple(args, "et:readlink",
4336 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004337 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004338 v = PySequence_GetItem(args, 0);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004339 if (v == NULL) {
4340 PyMem_Free(path);
4341 return NULL;
4342 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004343
4344 if (PyUnicode_Check(v)) {
4345 arg_is_unicode = 1;
4346 }
4347 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004348
Barry Warsaw53699e91996-12-10 23:23:01 +00004349 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004350 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004351 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004352 if (n < 0)
Neal Norwitzfca70052007-08-12 16:56:02 +00004353 return posix_error_with_allocated_filename(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004354
Neal Norwitzfca70052007-08-12 16:56:02 +00004355 PyMem_Free(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004356 v = PyString_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004357 if (arg_is_unicode) {
4358 PyObject *w;
4359
4360 w = PyUnicode_FromEncodedObject(v,
4361 Py_FileSystemDefaultEncoding,
4362 "strict");
4363 if (w != NULL) {
4364 Py_DECREF(v);
4365 v = w;
4366 }
4367 else {
4368 /* fall back to the original byte string, as
4369 discussed in patch #683592 */
4370 PyErr_Clear();
4371 }
4372 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004373 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004374}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004375#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004376
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004377
Guido van Rossumb6775db1994-08-01 11:34:53 +00004378#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004379PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004380"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004381Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004382
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004384posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004385{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004386 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004387}
4388#endif /* HAVE_SYMLINK */
4389
4390
4391#ifdef HAVE_TIMES
4392#ifndef HZ
4393#define HZ 60 /* Universal constant :-) */
4394#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004395
Guido van Rossumd48f2521997-12-05 22:19:34 +00004396#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4397static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004398system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004399{
4400 ULONG value = 0;
4401
4402 Py_BEGIN_ALLOW_THREADS
4403 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4404 Py_END_ALLOW_THREADS
4405
4406 return value;
4407}
4408
4409static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004410posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004411{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004412 /* Currently Only Uptime is Provided -- Others Later */
4413 return Py_BuildValue("ddddd",
4414 (double)0 /* t.tms_utime / HZ */,
4415 (double)0 /* t.tms_stime / HZ */,
4416 (double)0 /* t.tms_cutime / HZ */,
4417 (double)0 /* t.tms_cstime / HZ */,
4418 (double)system_uptime() / 1000);
4419}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004420#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004421static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004422posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004423{
4424 struct tms t;
4425 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004426 errno = 0;
4427 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004428 if (c == (clock_t) -1)
4429 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004430 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004431 (double)t.tms_utime / HZ,
4432 (double)t.tms_stime / HZ,
4433 (double)t.tms_cutime / HZ,
4434 (double)t.tms_cstime / HZ,
4435 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004436}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004437#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004438#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004439
4440
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004441#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004442#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004443static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004444posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004445{
4446 FILETIME create, exit, kernel, user;
4447 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004448 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004449 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4450 /* The fields of a FILETIME structure are the hi and lo part
4451 of a 64-bit value expressed in 100 nanosecond units.
4452 1e7 is one second in such units; 1e-7 the inverse.
4453 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4454 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004455 return Py_BuildValue(
4456 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004457 (double)(kernel.dwHighDateTime*429.4967296 +
4458 kernel.dwLowDateTime*1e-7),
4459 (double)(user.dwHighDateTime*429.4967296 +
4460 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004461 (double)0,
4462 (double)0,
4463 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004464}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004465#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004466
4467#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004468PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004469"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004470Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004471#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004472
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004473
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004474#ifdef HAVE_GETSID
4475PyDoc_STRVAR(posix_getsid__doc__,
4476"getsid(pid) -> sid\n\n\
4477Call the system call getsid().");
4478
4479static PyObject *
4480posix_getsid(PyObject *self, PyObject *args)
4481{
4482 int pid, sid;
4483 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4484 return NULL;
4485 sid = getsid(pid);
4486 if (sid < 0)
4487 return posix_error();
4488 return PyInt_FromLong((long)sid);
4489}
4490#endif /* HAVE_GETSID */
4491
4492
Guido van Rossumb6775db1994-08-01 11:34:53 +00004493#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004494PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004495"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004496Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004497
Barry Warsaw53699e91996-12-10 23:23:01 +00004498static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004499posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004500{
Guido van Rossum687dd131993-05-17 08:34:16 +00004501 if (setsid() < 0)
4502 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004503 Py_INCREF(Py_None);
4504 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004505}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004506#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004507
Guido van Rossumb6775db1994-08-01 11:34:53 +00004508#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004509PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004510"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004511Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004512
Barry Warsaw53699e91996-12-10 23:23:01 +00004513static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004514posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004515{
4516 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004517 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004518 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004519 if (setpgid(pid, pgrp) < 0)
4520 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004521 Py_INCREF(Py_None);
4522 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004523}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004524#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004525
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004526
Guido van Rossumb6775db1994-08-01 11:34:53 +00004527#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004528PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004529"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004530Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004531
Barry Warsaw53699e91996-12-10 23:23:01 +00004532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004533posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004534{
4535 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004536 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004537 return NULL;
4538 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004539 if (pgid < 0)
4540 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004541 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004542}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004543#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004544
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004545
Guido van Rossumb6775db1994-08-01 11:34:53 +00004546#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004547PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004548"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004549Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004550
Barry Warsaw53699e91996-12-10 23:23:01 +00004551static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004552posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004553{
4554 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004555 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004556 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004557 if (tcsetpgrp(fd, pgid) < 0)
4558 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004559 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004560 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004561}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004562#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004563
Guido van Rossum687dd131993-05-17 08:34:16 +00004564/* Functions acting on file descriptors */
4565
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004566PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004567"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004568Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004569
Barry Warsaw53699e91996-12-10 23:23:01 +00004570static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004571posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004572{
Mark Hammondef8b6542001-05-13 08:04:26 +00004573 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004574 int flag;
4575 int mode = 0777;
4576 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004577
4578#ifdef MS_WINDOWS
4579 if (unicode_file_names()) {
4580 PyUnicodeObject *po;
4581 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4582 Py_BEGIN_ALLOW_THREADS
4583 /* PyUnicode_AS_UNICODE OK without thread
4584 lock as it is a simple dereference. */
4585 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4586 Py_END_ALLOW_THREADS
4587 if (fd < 0)
4588 return posix_error();
4589 return PyInt_FromLong((long)fd);
4590 }
4591 /* Drop the argument parsing error as narrow strings
4592 are also valid. */
4593 PyErr_Clear();
4594 }
4595#endif
4596
Tim Peters5aa91602002-01-30 05:46:57 +00004597 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004598 Py_FileSystemDefaultEncoding, &file,
4599 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004600 return NULL;
4601
Barry Warsaw53699e91996-12-10 23:23:01 +00004602 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004603 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004604 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004605 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004606 return posix_error_with_allocated_filename(file);
4607 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004608 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004609}
4610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004611
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004612PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004613"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004614Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004615
Barry Warsaw53699e91996-12-10 23:23:01 +00004616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004617posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004618{
4619 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004620 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004621 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004622 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004623 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004624 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004625 if (res < 0)
4626 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004627 Py_INCREF(Py_None);
4628 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004629}
4630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004631
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004632PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004633"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004634Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004635
Barry Warsaw53699e91996-12-10 23:23:01 +00004636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004637posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004638{
4639 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004640 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004641 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004642 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004643 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004644 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004645 if (fd < 0)
4646 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004647 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004648}
4649
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004650
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004651PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00004652"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004653Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004654
Barry Warsaw53699e91996-12-10 23:23:01 +00004655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004656posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004657{
4658 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004659 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004660 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004661 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004662 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004663 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004664 if (res < 0)
4665 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004666 Py_INCREF(Py_None);
4667 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004668}
4669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004670
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004671PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004672"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004673Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004674
Barry Warsaw53699e91996-12-10 23:23:01 +00004675static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004676posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004677{
4678 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004679#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004680 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004681#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004682 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004683#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004684 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004685 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004686 return NULL;
4687#ifdef SEEK_SET
4688 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4689 switch (how) {
4690 case 0: how = SEEK_SET; break;
4691 case 1: how = SEEK_CUR; break;
4692 case 2: how = SEEK_END; break;
4693 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004694#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004695
4696#if !defined(HAVE_LARGEFILE_SUPPORT)
4697 pos = PyInt_AsLong(posobj);
4698#else
4699 pos = PyLong_Check(posobj) ?
4700 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4701#endif
4702 if (PyErr_Occurred())
4703 return NULL;
4704
Barry Warsaw53699e91996-12-10 23:23:01 +00004705 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004706#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004707 res = _lseeki64(fd, pos, how);
4708#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004709 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004710#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004711 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004712 if (res < 0)
4713 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004714
4715#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004716 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004717#else
4718 return PyLong_FromLongLong(res);
4719#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004720}
4721
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004722
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004723PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004724"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004725Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004726
Barry Warsaw53699e91996-12-10 23:23:01 +00004727static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004728posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004729{
Guido van Rossum572dbf82007-04-27 23:53:51 +00004730 int fd, size;
4731 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004732 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004733 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004734 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00004735 if (size < 0) {
4736 errno = EINVAL;
4737 return posix_error();
4738 }
Guido van Rossum572dbf82007-04-27 23:53:51 +00004739 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004740 if (buffer == NULL)
4741 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004742 Py_BEGIN_ALLOW_THREADS
Guido van Rossum572dbf82007-04-27 23:53:51 +00004743 n = read(fd, PyBytes_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004744 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004745 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004746 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004747 return posix_error();
4748 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004749 if (n != size)
Guido van Rossum572dbf82007-04-27 23:53:51 +00004750 PyBytes_Resize(buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004751 return buffer;
4752}
4753
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004754
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004755PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004756"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004757Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004758
Barry Warsaw53699e91996-12-10 23:23:01 +00004759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004760posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004761{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004762 int fd;
4763 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00004764 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004765
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004766 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004767 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004768 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004769 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004770 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004771 if (size < 0)
4772 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004773 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004774}
4775
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004776
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004777PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004778"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004779Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004780
Barry Warsaw53699e91996-12-10 23:23:01 +00004781static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004782posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004783{
4784 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004785 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004786 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004787 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004788 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00004789#ifdef __VMS
4790 /* on OpenVMS we must ensure that all bytes are written to the file */
4791 fsync(fd);
4792#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004793 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004794 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004795 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00004796 if (res != 0) {
4797#ifdef MS_WINDOWS
4798 return win32_error("fstat", NULL);
4799#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004800 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00004801#endif
4802 }
Tim Peters5aa91602002-01-30 05:46:57 +00004803
Martin v. Löwis14694662006-02-03 12:54:16 +00004804 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004805}
4806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004807PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004808"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004809Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004810connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004811
4812static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004813posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004814{
4815 int fd;
4816 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4817 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004818 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004819}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004820
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004821#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004822PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004823"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004824Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004825
Barry Warsaw53699e91996-12-10 23:23:01 +00004826static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004827posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00004828{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004829#if defined(PYOS_OS2)
4830 HFILE read, write;
4831 APIRET rc;
4832
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004833 Py_BEGIN_ALLOW_THREADS
4834 rc = DosCreatePipe( &read, &write, 4096);
4835 Py_END_ALLOW_THREADS
4836 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004837 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004838
4839 return Py_BuildValue("(ii)", read, write);
4840#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004841#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004842 int fds[2];
4843 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00004844 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004845 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004846 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004847 if (res != 0)
4848 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004849 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004850#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004851 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004852 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004853 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00004854 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004855 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004856 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004857 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004859 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4860 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004861 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004862#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004863#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004864}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004865#endif /* HAVE_PIPE */
4866
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004867
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004868#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004869PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004870"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004871Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004872
Barry Warsaw53699e91996-12-10 23:23:01 +00004873static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004874posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004875{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004876 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004877 int mode = 0666;
4878 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004879 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004880 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004881 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004882 res = mkfifo(filename, mode);
4883 Py_END_ALLOW_THREADS
4884 if (res < 0)
4885 return posix_error();
4886 Py_INCREF(Py_None);
4887 return Py_None;
4888}
4889#endif
4890
4891
Neal Norwitz11690112002-07-30 01:08:28 +00004892#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004893PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004894"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004895Create a filesystem node (file, device special file or named pipe)\n\
4896named filename. mode specifies both the permissions to use and the\n\
4897type of node to be created, being combined (bitwise OR) with one of\n\
4898S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004899device defines the newly created device special file (probably using\n\
4900os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004901
4902
4903static PyObject *
4904posix_mknod(PyObject *self, PyObject *args)
4905{
4906 char *filename;
4907 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004908 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004909 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00004910 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004911 return NULL;
4912 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004913 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00004914 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004915 if (res < 0)
4916 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004917 Py_INCREF(Py_None);
4918 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004919}
4920#endif
4921
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004922#ifdef HAVE_DEVICE_MACROS
4923PyDoc_STRVAR(posix_major__doc__,
4924"major(device) -> major number\n\
4925Extracts a device major number from a raw device number.");
4926
4927static PyObject *
4928posix_major(PyObject *self, PyObject *args)
4929{
4930 int device;
4931 if (!PyArg_ParseTuple(args, "i:major", &device))
4932 return NULL;
4933 return PyInt_FromLong((long)major(device));
4934}
4935
4936PyDoc_STRVAR(posix_minor__doc__,
4937"minor(device) -> minor number\n\
4938Extracts a device minor number from a raw device number.");
4939
4940static PyObject *
4941posix_minor(PyObject *self, PyObject *args)
4942{
4943 int device;
4944 if (!PyArg_ParseTuple(args, "i:minor", &device))
4945 return NULL;
4946 return PyInt_FromLong((long)minor(device));
4947}
4948
4949PyDoc_STRVAR(posix_makedev__doc__,
4950"makedev(major, minor) -> device number\n\
4951Composes a raw device number from the major and minor device numbers.");
4952
4953static PyObject *
4954posix_makedev(PyObject *self, PyObject *args)
4955{
4956 int major, minor;
4957 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
4958 return NULL;
4959 return PyInt_FromLong((long)makedev(major, minor));
4960}
4961#endif /* device macros */
4962
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004963
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004964#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004965PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004966"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004967Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004968
Barry Warsaw53699e91996-12-10 23:23:01 +00004969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004970posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004971{
4972 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004973 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004974 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004975 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004976
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004977 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004978 return NULL;
4979
4980#if !defined(HAVE_LARGEFILE_SUPPORT)
4981 length = PyInt_AsLong(lenobj);
4982#else
4983 length = PyLong_Check(lenobj) ?
4984 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4985#endif
4986 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004987 return NULL;
4988
Barry Warsaw53699e91996-12-10 23:23:01 +00004989 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004990 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004991 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004992 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004993 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004994 return NULL;
4995 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004996 Py_INCREF(Py_None);
4997 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004998}
4999#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005000
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005001#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005002PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005003"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005004Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005005
Fred Drake762e2061999-08-26 17:23:54 +00005006/* Save putenv() parameters as values here, so we can collect them when they
5007 * get re-set with another call for the same key. */
5008static PyObject *posix_putenv_garbage;
5009
Tim Peters5aa91602002-01-30 05:46:57 +00005010static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005011posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005012{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005013#ifdef MS_WINDOWS
5014 wchar_t *s1, *s2;
5015 wchar_t *newenv;
5016#else
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005017 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005018 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005019#endif
Fred Drake762e2061999-08-26 17:23:54 +00005020 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005021 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005022
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005023 if (!PyArg_ParseTuple(args,
5024#ifdef MS_WINDOWS
5025 "uu:putenv",
5026#else
5027 "ss:putenv",
5028#endif
5029 &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005030 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005031
5032#if defined(PYOS_OS2)
5033 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5034 APIRET rc;
5035
Guido van Rossumd48f2521997-12-05 22:19:34 +00005036 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5037 if (rc != NO_ERROR)
5038 return os2_error(rc);
5039
5040 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5041 APIRET rc;
5042
Guido van Rossumd48f2521997-12-05 22:19:34 +00005043 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5044 if (rc != NO_ERROR)
5045 return os2_error(rc);
5046 } else {
5047#endif
Fred Drake762e2061999-08-26 17:23:54 +00005048 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005049 /* len includes space for a trailing \0; the size arg to
5050 PyString_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005051#ifdef MS_WINDOWS
5052 len = wcslen(s1) + wcslen(s2) + 2;
5053 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5054#else
5055 len = strlen(s1) + strlen(s2) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00005056 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005057#endif
Fred Drake762e2061999-08-26 17:23:54 +00005058 if (newstr == NULL)
5059 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005060#ifdef MS_WINDOWS
5061 newenv = PyUnicode_AsUnicode(newstr);
5062 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5063 if (_wputenv(newenv)) {
5064 Py_DECREF(newstr);
5065 posix_error();
5066 return NULL;
5067 }
5068#else
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005069 newenv = PyString_AS_STRING(newstr);
5070 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5071 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005072 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005073 posix_error();
5074 return NULL;
5075 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005076#endif
Fred Drake762e2061999-08-26 17:23:54 +00005077 /* Install the first arg and newstr in posix_putenv_garbage;
5078 * this will cause previous value to be collected. This has to
5079 * happen after the real putenv() call because the old value
5080 * was still accessible until then. */
5081 if (PyDict_SetItem(posix_putenv_garbage,
5082 PyTuple_GET_ITEM(args, 0), newstr)) {
5083 /* really not much we can do; just leak */
5084 PyErr_Clear();
5085 }
5086 else {
5087 Py_DECREF(newstr);
5088 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005089
5090#if defined(PYOS_OS2)
5091 }
5092#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005093 Py_INCREF(Py_None);
5094 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005095}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005096#endif /* putenv */
5097
Guido van Rossumc524d952001-10-19 01:31:59 +00005098#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005099PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005100"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005101Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005102
5103static PyObject *
5104posix_unsetenv(PyObject *self, PyObject *args)
5105{
5106 char *s1;
5107
5108 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5109 return NULL;
5110
5111 unsetenv(s1);
5112
5113 /* Remove the key from posix_putenv_garbage;
5114 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005115 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005116 * old value was still accessible until then.
5117 */
5118 if (PyDict_DelItem(posix_putenv_garbage,
5119 PyTuple_GET_ITEM(args, 0))) {
5120 /* really not much we can do; just leak */
5121 PyErr_Clear();
5122 }
5123
5124 Py_INCREF(Py_None);
5125 return Py_None;
5126}
5127#endif /* unsetenv */
5128
Guido van Rossumb6a47161997-09-15 22:54:34 +00005129#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005130PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005131"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005132Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005133
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005135posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005136{
5137 int code;
5138 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005139 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005140 return NULL;
5141 message = strerror(code);
5142 if (message == NULL) {
5143 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005144 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005145 return NULL;
5146 }
Neal Norwitz93c56822007-08-26 07:10:06 +00005147 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005148}
5149#endif /* strerror */
5150
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005151
Guido van Rossumc9641791998-08-04 15:26:23 +00005152#ifdef HAVE_SYS_WAIT_H
5153
Fred Drake106c1a02002-04-23 15:58:02 +00005154#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005155PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005156"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005157Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005158
5159static PyObject *
5160posix_WCOREDUMP(PyObject *self, PyObject *args)
5161{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005162 WAIT_TYPE status;
5163 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005164
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005165 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005166 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005167
5168 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005169}
5170#endif /* WCOREDUMP */
5171
5172#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005173PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005174"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005175Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005176job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005177
5178static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005179posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005180{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005181 WAIT_TYPE status;
5182 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005183
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005184 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005185 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005186
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005187 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005188}
5189#endif /* WIFCONTINUED */
5190
Guido van Rossumc9641791998-08-04 15:26:23 +00005191#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005192PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005193"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005194Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005195
5196static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005197posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005198{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005199 WAIT_TYPE status;
5200 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005201
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005202 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005203 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005204
Fred Drake106c1a02002-04-23 15:58:02 +00005205 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005206}
5207#endif /* WIFSTOPPED */
5208
5209#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005210PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005211"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005212Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005213
5214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005215posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005216{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005217 WAIT_TYPE status;
5218 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005219
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005220 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005221 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005222
Fred Drake106c1a02002-04-23 15:58:02 +00005223 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005224}
5225#endif /* WIFSIGNALED */
5226
5227#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005228PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005229"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005230Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005231system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005232
5233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005234posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005235{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005236 WAIT_TYPE status;
5237 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005238
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005239 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005240 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005241
Fred Drake106c1a02002-04-23 15:58:02 +00005242 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005243}
5244#endif /* WIFEXITED */
5245
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005246#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005247PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005248"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005249Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005250
5251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005252posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005253{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005254 WAIT_TYPE status;
5255 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005256
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005257 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005258 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005259
Guido van Rossumc9641791998-08-04 15:26:23 +00005260 return Py_BuildValue("i", WEXITSTATUS(status));
5261}
5262#endif /* WEXITSTATUS */
5263
5264#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005265PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005266"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005267Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005268value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005269
5270static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005271posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005272{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005273 WAIT_TYPE status;
5274 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005275
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005276 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005277 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005278
Guido van Rossumc9641791998-08-04 15:26:23 +00005279 return Py_BuildValue("i", WTERMSIG(status));
5280}
5281#endif /* WTERMSIG */
5282
5283#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005284PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005285"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005286Return the signal that stopped the process that provided\n\
5287the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005288
5289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005290posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005291{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005292 WAIT_TYPE status;
5293 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005294
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005295 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005296 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005297
Guido van Rossumc9641791998-08-04 15:26:23 +00005298 return Py_BuildValue("i", WSTOPSIG(status));
5299}
5300#endif /* WSTOPSIG */
5301
5302#endif /* HAVE_SYS_WAIT_H */
5303
5304
Thomas Wouters477c8d52006-05-27 19:21:47 +00005305#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005306#ifdef _SCO_DS
5307/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5308 needed definitions in sys/statvfs.h */
5309#define _SVID3
5310#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005311#include <sys/statvfs.h>
5312
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005313static PyObject*
5314_pystatvfs_fromstructstatvfs(struct statvfs st) {
5315 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5316 if (v == NULL)
5317 return NULL;
5318
5319#if !defined(HAVE_LARGEFILE_SUPPORT)
5320 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5321 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5322 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5323 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5324 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5325 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5326 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5327 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5328 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5329 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5330#else
5331 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5332 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005333 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005334 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005335 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005336 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005337 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005338 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005339 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005340 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005341 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005342 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005343 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005344 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005345 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5346 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5347#endif
5348
5349 return v;
5350}
5351
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005352PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005353"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005354Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005355
5356static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005357posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005358{
5359 int fd, res;
5360 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005361
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005362 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005363 return NULL;
5364 Py_BEGIN_ALLOW_THREADS
5365 res = fstatvfs(fd, &st);
5366 Py_END_ALLOW_THREADS
5367 if (res != 0)
5368 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005369
5370 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005371}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005372#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005373
5374
Thomas Wouters477c8d52006-05-27 19:21:47 +00005375#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005376#include <sys/statvfs.h>
5377
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005378PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005379"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005381
5382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005383posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005384{
5385 char *path;
5386 int res;
5387 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005388 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005389 return NULL;
5390 Py_BEGIN_ALLOW_THREADS
5391 res = statvfs(path, &st);
5392 Py_END_ALLOW_THREADS
5393 if (res != 0)
5394 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005395
5396 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005397}
5398#endif /* HAVE_STATVFS */
5399
Fred Drakec9680921999-12-13 16:37:25 +00005400/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5401 * It maps strings representing configuration variable names to
5402 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005403 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005404 * rarely-used constants. There are three separate tables that use
5405 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005406 *
5407 * This code is always included, even if none of the interfaces that
5408 * need it are included. The #if hackery needed to avoid it would be
5409 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005410 */
5411struct constdef {
5412 char *name;
5413 long value;
5414};
5415
Fred Drake12c6e2d1999-12-14 21:25:03 +00005416static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005417conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005418 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005419{
5420 if (PyInt_Check(arg)) {
5421 *valuep = PyInt_AS_LONG(arg);
5422 return 1;
5423 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005424 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005425 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005426 size_t lo = 0;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005427 size_t mid;
Fred Drake699f3522000-06-29 21:12:41 +00005428 size_t hi = tablesize;
5429 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005430 const char *confname;
5431 Py_ssize_t namelen;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005432 if (!PyUnicode_Check(arg)) {
Guido van Rossumbce56a62007-05-10 18:04:33 +00005433 PyErr_SetString(PyExc_TypeError,
5434 "configuration names must be strings or integers");
5435 return 0;
5436 }
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005437 confname = PyUnicode_AsString(arg);
5438 if (confname == NULL)
5439 return 0;
5440 namelen = strlen(confname);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005441 while (lo < hi) {
5442 mid = (lo + hi) / 2;
5443 cmp = strcmp(confname, table[mid].name);
5444 if (cmp < 0)
5445 hi = mid;
5446 else if (cmp > 0)
5447 lo = mid + 1;
5448 else {
5449 *valuep = table[mid].value;
5450 return 1;
5451 }
5452 }
5453 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005454 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005455 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005456}
5457
5458
5459#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5460static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005461#ifdef _PC_ABI_AIO_XFER_MAX
5462 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5463#endif
5464#ifdef _PC_ABI_ASYNC_IO
5465 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5466#endif
Fred Drakec9680921999-12-13 16:37:25 +00005467#ifdef _PC_ASYNC_IO
5468 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5469#endif
5470#ifdef _PC_CHOWN_RESTRICTED
5471 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5472#endif
5473#ifdef _PC_FILESIZEBITS
5474 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5475#endif
5476#ifdef _PC_LAST
5477 {"PC_LAST", _PC_LAST},
5478#endif
5479#ifdef _PC_LINK_MAX
5480 {"PC_LINK_MAX", _PC_LINK_MAX},
5481#endif
5482#ifdef _PC_MAX_CANON
5483 {"PC_MAX_CANON", _PC_MAX_CANON},
5484#endif
5485#ifdef _PC_MAX_INPUT
5486 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5487#endif
5488#ifdef _PC_NAME_MAX
5489 {"PC_NAME_MAX", _PC_NAME_MAX},
5490#endif
5491#ifdef _PC_NO_TRUNC
5492 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5493#endif
5494#ifdef _PC_PATH_MAX
5495 {"PC_PATH_MAX", _PC_PATH_MAX},
5496#endif
5497#ifdef _PC_PIPE_BUF
5498 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5499#endif
5500#ifdef _PC_PRIO_IO
5501 {"PC_PRIO_IO", _PC_PRIO_IO},
5502#endif
5503#ifdef _PC_SOCK_MAXBUF
5504 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5505#endif
5506#ifdef _PC_SYNC_IO
5507 {"PC_SYNC_IO", _PC_SYNC_IO},
5508#endif
5509#ifdef _PC_VDISABLE
5510 {"PC_VDISABLE", _PC_VDISABLE},
5511#endif
5512};
5513
Fred Drakec9680921999-12-13 16:37:25 +00005514static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005515conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005516{
5517 return conv_confname(arg, valuep, posix_constants_pathconf,
5518 sizeof(posix_constants_pathconf)
5519 / sizeof(struct constdef));
5520}
5521#endif
5522
5523#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005524PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005525"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005526Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005527If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005528
5529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005530posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005531{
5532 PyObject *result = NULL;
5533 int name, fd;
5534
Fred Drake12c6e2d1999-12-14 21:25:03 +00005535 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5536 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005537 long limit;
5538
5539 errno = 0;
5540 limit = fpathconf(fd, name);
5541 if (limit == -1 && errno != 0)
5542 posix_error();
5543 else
5544 result = PyInt_FromLong(limit);
5545 }
5546 return result;
5547}
5548#endif
5549
5550
5551#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005552PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005553"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005554Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005555If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005556
5557static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005558posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005559{
5560 PyObject *result = NULL;
5561 int name;
5562 char *path;
5563
5564 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5565 conv_path_confname, &name)) {
5566 long limit;
5567
5568 errno = 0;
5569 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005570 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005571 if (errno == EINVAL)
5572 /* could be a path or name problem */
5573 posix_error();
5574 else
5575 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005576 }
Fred Drakec9680921999-12-13 16:37:25 +00005577 else
5578 result = PyInt_FromLong(limit);
5579 }
5580 return result;
5581}
5582#endif
5583
5584#ifdef HAVE_CONFSTR
5585static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005586#ifdef _CS_ARCHITECTURE
5587 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5588#endif
5589#ifdef _CS_HOSTNAME
5590 {"CS_HOSTNAME", _CS_HOSTNAME},
5591#endif
5592#ifdef _CS_HW_PROVIDER
5593 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5594#endif
5595#ifdef _CS_HW_SERIAL
5596 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5597#endif
5598#ifdef _CS_INITTAB_NAME
5599 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5600#endif
Fred Drakec9680921999-12-13 16:37:25 +00005601#ifdef _CS_LFS64_CFLAGS
5602 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5603#endif
5604#ifdef _CS_LFS64_LDFLAGS
5605 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5606#endif
5607#ifdef _CS_LFS64_LIBS
5608 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5609#endif
5610#ifdef _CS_LFS64_LINTFLAGS
5611 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5612#endif
5613#ifdef _CS_LFS_CFLAGS
5614 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5615#endif
5616#ifdef _CS_LFS_LDFLAGS
5617 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5618#endif
5619#ifdef _CS_LFS_LIBS
5620 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5621#endif
5622#ifdef _CS_LFS_LINTFLAGS
5623 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5624#endif
Fred Draked86ed291999-12-15 15:34:33 +00005625#ifdef _CS_MACHINE
5626 {"CS_MACHINE", _CS_MACHINE},
5627#endif
Fred Drakec9680921999-12-13 16:37:25 +00005628#ifdef _CS_PATH
5629 {"CS_PATH", _CS_PATH},
5630#endif
Fred Draked86ed291999-12-15 15:34:33 +00005631#ifdef _CS_RELEASE
5632 {"CS_RELEASE", _CS_RELEASE},
5633#endif
5634#ifdef _CS_SRPC_DOMAIN
5635 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5636#endif
5637#ifdef _CS_SYSNAME
5638 {"CS_SYSNAME", _CS_SYSNAME},
5639#endif
5640#ifdef _CS_VERSION
5641 {"CS_VERSION", _CS_VERSION},
5642#endif
Fred Drakec9680921999-12-13 16:37:25 +00005643#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5644 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5645#endif
5646#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5647 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5648#endif
5649#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5650 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5651#endif
5652#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5653 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5654#endif
5655#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5656 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5657#endif
5658#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5659 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5660#endif
5661#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5662 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5663#endif
5664#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5665 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5666#endif
5667#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5668 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5669#endif
5670#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5671 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5672#endif
5673#ifdef _CS_XBS5_LP64_OFF64_LIBS
5674 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5675#endif
5676#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5677 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5678#endif
5679#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5680 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5681#endif
5682#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5683 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5684#endif
5685#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5686 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5687#endif
5688#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5689 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5690#endif
Fred Draked86ed291999-12-15 15:34:33 +00005691#ifdef _MIPS_CS_AVAIL_PROCESSORS
5692 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5693#endif
5694#ifdef _MIPS_CS_BASE
5695 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5696#endif
5697#ifdef _MIPS_CS_HOSTID
5698 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5699#endif
5700#ifdef _MIPS_CS_HW_NAME
5701 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5702#endif
5703#ifdef _MIPS_CS_NUM_PROCESSORS
5704 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5705#endif
5706#ifdef _MIPS_CS_OSREL_MAJ
5707 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5708#endif
5709#ifdef _MIPS_CS_OSREL_MIN
5710 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5711#endif
5712#ifdef _MIPS_CS_OSREL_PATCH
5713 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5714#endif
5715#ifdef _MIPS_CS_OS_NAME
5716 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5717#endif
5718#ifdef _MIPS_CS_OS_PROVIDER
5719 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5720#endif
5721#ifdef _MIPS_CS_PROCESSORS
5722 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5723#endif
5724#ifdef _MIPS_CS_SERIAL
5725 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5726#endif
5727#ifdef _MIPS_CS_VENDOR
5728 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5729#endif
Fred Drakec9680921999-12-13 16:37:25 +00005730};
5731
5732static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005733conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005734{
5735 return conv_confname(arg, valuep, posix_constants_confstr,
5736 sizeof(posix_constants_confstr)
5737 / sizeof(struct constdef));
5738}
5739
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005740PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005741"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005742Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005743
5744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005745posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005746{
5747 PyObject *result = NULL;
5748 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005749 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00005750
5751 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005752 int len;
Fred Drakec9680921999-12-13 16:37:25 +00005753
Fred Drakec9680921999-12-13 16:37:25 +00005754 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005755 len = confstr(name, buffer, sizeof(buffer));
5756 if (len == 0) {
5757 if (errno) {
5758 posix_error();
5759 }
5760 else {
5761 result = Py_None;
5762 Py_INCREF(Py_None);
5763 }
Fred Drakec9680921999-12-13 16:37:25 +00005764 }
5765 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005766 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00005767 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005768 if (result != NULL)
Neal Norwitz93c56822007-08-26 07:10:06 +00005769 confstr(name, PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00005770 }
5771 else
Neal Norwitz93c56822007-08-26 07:10:06 +00005772 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005773 }
5774 }
5775 return result;
5776}
5777#endif
5778
5779
5780#ifdef HAVE_SYSCONF
5781static struct constdef posix_constants_sysconf[] = {
5782#ifdef _SC_2_CHAR_TERM
5783 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5784#endif
5785#ifdef _SC_2_C_BIND
5786 {"SC_2_C_BIND", _SC_2_C_BIND},
5787#endif
5788#ifdef _SC_2_C_DEV
5789 {"SC_2_C_DEV", _SC_2_C_DEV},
5790#endif
5791#ifdef _SC_2_C_VERSION
5792 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5793#endif
5794#ifdef _SC_2_FORT_DEV
5795 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5796#endif
5797#ifdef _SC_2_FORT_RUN
5798 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5799#endif
5800#ifdef _SC_2_LOCALEDEF
5801 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5802#endif
5803#ifdef _SC_2_SW_DEV
5804 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5805#endif
5806#ifdef _SC_2_UPE
5807 {"SC_2_UPE", _SC_2_UPE},
5808#endif
5809#ifdef _SC_2_VERSION
5810 {"SC_2_VERSION", _SC_2_VERSION},
5811#endif
Fred Draked86ed291999-12-15 15:34:33 +00005812#ifdef _SC_ABI_ASYNCHRONOUS_IO
5813 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5814#endif
5815#ifdef _SC_ACL
5816 {"SC_ACL", _SC_ACL},
5817#endif
Fred Drakec9680921999-12-13 16:37:25 +00005818#ifdef _SC_AIO_LISTIO_MAX
5819 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5820#endif
Fred Drakec9680921999-12-13 16:37:25 +00005821#ifdef _SC_AIO_MAX
5822 {"SC_AIO_MAX", _SC_AIO_MAX},
5823#endif
5824#ifdef _SC_AIO_PRIO_DELTA_MAX
5825 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5826#endif
5827#ifdef _SC_ARG_MAX
5828 {"SC_ARG_MAX", _SC_ARG_MAX},
5829#endif
5830#ifdef _SC_ASYNCHRONOUS_IO
5831 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5832#endif
5833#ifdef _SC_ATEXIT_MAX
5834 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5835#endif
Fred Draked86ed291999-12-15 15:34:33 +00005836#ifdef _SC_AUDIT
5837 {"SC_AUDIT", _SC_AUDIT},
5838#endif
Fred Drakec9680921999-12-13 16:37:25 +00005839#ifdef _SC_AVPHYS_PAGES
5840 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5841#endif
5842#ifdef _SC_BC_BASE_MAX
5843 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5844#endif
5845#ifdef _SC_BC_DIM_MAX
5846 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5847#endif
5848#ifdef _SC_BC_SCALE_MAX
5849 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5850#endif
5851#ifdef _SC_BC_STRING_MAX
5852 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5853#endif
Fred Draked86ed291999-12-15 15:34:33 +00005854#ifdef _SC_CAP
5855 {"SC_CAP", _SC_CAP},
5856#endif
Fred Drakec9680921999-12-13 16:37:25 +00005857#ifdef _SC_CHARCLASS_NAME_MAX
5858 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5859#endif
5860#ifdef _SC_CHAR_BIT
5861 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5862#endif
5863#ifdef _SC_CHAR_MAX
5864 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5865#endif
5866#ifdef _SC_CHAR_MIN
5867 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5868#endif
5869#ifdef _SC_CHILD_MAX
5870 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5871#endif
5872#ifdef _SC_CLK_TCK
5873 {"SC_CLK_TCK", _SC_CLK_TCK},
5874#endif
5875#ifdef _SC_COHER_BLKSZ
5876 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5877#endif
5878#ifdef _SC_COLL_WEIGHTS_MAX
5879 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5880#endif
5881#ifdef _SC_DCACHE_ASSOC
5882 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5883#endif
5884#ifdef _SC_DCACHE_BLKSZ
5885 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5886#endif
5887#ifdef _SC_DCACHE_LINESZ
5888 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5889#endif
5890#ifdef _SC_DCACHE_SZ
5891 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5892#endif
5893#ifdef _SC_DCACHE_TBLKSZ
5894 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5895#endif
5896#ifdef _SC_DELAYTIMER_MAX
5897 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5898#endif
5899#ifdef _SC_EQUIV_CLASS_MAX
5900 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5901#endif
5902#ifdef _SC_EXPR_NEST_MAX
5903 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5904#endif
5905#ifdef _SC_FSYNC
5906 {"SC_FSYNC", _SC_FSYNC},
5907#endif
5908#ifdef _SC_GETGR_R_SIZE_MAX
5909 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5910#endif
5911#ifdef _SC_GETPW_R_SIZE_MAX
5912 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5913#endif
5914#ifdef _SC_ICACHE_ASSOC
5915 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5916#endif
5917#ifdef _SC_ICACHE_BLKSZ
5918 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5919#endif
5920#ifdef _SC_ICACHE_LINESZ
5921 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5922#endif
5923#ifdef _SC_ICACHE_SZ
5924 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5925#endif
Fred Draked86ed291999-12-15 15:34:33 +00005926#ifdef _SC_INF
5927 {"SC_INF", _SC_INF},
5928#endif
Fred Drakec9680921999-12-13 16:37:25 +00005929#ifdef _SC_INT_MAX
5930 {"SC_INT_MAX", _SC_INT_MAX},
5931#endif
5932#ifdef _SC_INT_MIN
5933 {"SC_INT_MIN", _SC_INT_MIN},
5934#endif
5935#ifdef _SC_IOV_MAX
5936 {"SC_IOV_MAX", _SC_IOV_MAX},
5937#endif
Fred Draked86ed291999-12-15 15:34:33 +00005938#ifdef _SC_IP_SECOPTS
5939 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5940#endif
Fred Drakec9680921999-12-13 16:37:25 +00005941#ifdef _SC_JOB_CONTROL
5942 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5943#endif
Fred Draked86ed291999-12-15 15:34:33 +00005944#ifdef _SC_KERN_POINTERS
5945 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5946#endif
5947#ifdef _SC_KERN_SIM
5948 {"SC_KERN_SIM", _SC_KERN_SIM},
5949#endif
Fred Drakec9680921999-12-13 16:37:25 +00005950#ifdef _SC_LINE_MAX
5951 {"SC_LINE_MAX", _SC_LINE_MAX},
5952#endif
5953#ifdef _SC_LOGIN_NAME_MAX
5954 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5955#endif
5956#ifdef _SC_LOGNAME_MAX
5957 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5958#endif
5959#ifdef _SC_LONG_BIT
5960 {"SC_LONG_BIT", _SC_LONG_BIT},
5961#endif
Fred Draked86ed291999-12-15 15:34:33 +00005962#ifdef _SC_MAC
5963 {"SC_MAC", _SC_MAC},
5964#endif
Fred Drakec9680921999-12-13 16:37:25 +00005965#ifdef _SC_MAPPED_FILES
5966 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5967#endif
5968#ifdef _SC_MAXPID
5969 {"SC_MAXPID", _SC_MAXPID},
5970#endif
5971#ifdef _SC_MB_LEN_MAX
5972 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5973#endif
5974#ifdef _SC_MEMLOCK
5975 {"SC_MEMLOCK", _SC_MEMLOCK},
5976#endif
5977#ifdef _SC_MEMLOCK_RANGE
5978 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5979#endif
5980#ifdef _SC_MEMORY_PROTECTION
5981 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5982#endif
5983#ifdef _SC_MESSAGE_PASSING
5984 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5985#endif
Fred Draked86ed291999-12-15 15:34:33 +00005986#ifdef _SC_MMAP_FIXED_ALIGNMENT
5987 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5988#endif
Fred Drakec9680921999-12-13 16:37:25 +00005989#ifdef _SC_MQ_OPEN_MAX
5990 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5991#endif
5992#ifdef _SC_MQ_PRIO_MAX
5993 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5994#endif
Fred Draked86ed291999-12-15 15:34:33 +00005995#ifdef _SC_NACLS_MAX
5996 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5997#endif
Fred Drakec9680921999-12-13 16:37:25 +00005998#ifdef _SC_NGROUPS_MAX
5999 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6000#endif
6001#ifdef _SC_NL_ARGMAX
6002 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6003#endif
6004#ifdef _SC_NL_LANGMAX
6005 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6006#endif
6007#ifdef _SC_NL_MSGMAX
6008 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6009#endif
6010#ifdef _SC_NL_NMAX
6011 {"SC_NL_NMAX", _SC_NL_NMAX},
6012#endif
6013#ifdef _SC_NL_SETMAX
6014 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6015#endif
6016#ifdef _SC_NL_TEXTMAX
6017 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6018#endif
6019#ifdef _SC_NPROCESSORS_CONF
6020 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6021#endif
6022#ifdef _SC_NPROCESSORS_ONLN
6023 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6024#endif
Fred Draked86ed291999-12-15 15:34:33 +00006025#ifdef _SC_NPROC_CONF
6026 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6027#endif
6028#ifdef _SC_NPROC_ONLN
6029 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6030#endif
Fred Drakec9680921999-12-13 16:37:25 +00006031#ifdef _SC_NZERO
6032 {"SC_NZERO", _SC_NZERO},
6033#endif
6034#ifdef _SC_OPEN_MAX
6035 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6036#endif
6037#ifdef _SC_PAGESIZE
6038 {"SC_PAGESIZE", _SC_PAGESIZE},
6039#endif
6040#ifdef _SC_PAGE_SIZE
6041 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6042#endif
6043#ifdef _SC_PASS_MAX
6044 {"SC_PASS_MAX", _SC_PASS_MAX},
6045#endif
6046#ifdef _SC_PHYS_PAGES
6047 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6048#endif
6049#ifdef _SC_PII
6050 {"SC_PII", _SC_PII},
6051#endif
6052#ifdef _SC_PII_INTERNET
6053 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6054#endif
6055#ifdef _SC_PII_INTERNET_DGRAM
6056 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6057#endif
6058#ifdef _SC_PII_INTERNET_STREAM
6059 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6060#endif
6061#ifdef _SC_PII_OSI
6062 {"SC_PII_OSI", _SC_PII_OSI},
6063#endif
6064#ifdef _SC_PII_OSI_CLTS
6065 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6066#endif
6067#ifdef _SC_PII_OSI_COTS
6068 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6069#endif
6070#ifdef _SC_PII_OSI_M
6071 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6072#endif
6073#ifdef _SC_PII_SOCKET
6074 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6075#endif
6076#ifdef _SC_PII_XTI
6077 {"SC_PII_XTI", _SC_PII_XTI},
6078#endif
6079#ifdef _SC_POLL
6080 {"SC_POLL", _SC_POLL},
6081#endif
6082#ifdef _SC_PRIORITIZED_IO
6083 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6084#endif
6085#ifdef _SC_PRIORITY_SCHEDULING
6086 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6087#endif
6088#ifdef _SC_REALTIME_SIGNALS
6089 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6090#endif
6091#ifdef _SC_RE_DUP_MAX
6092 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6093#endif
6094#ifdef _SC_RTSIG_MAX
6095 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6096#endif
6097#ifdef _SC_SAVED_IDS
6098 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6099#endif
6100#ifdef _SC_SCHAR_MAX
6101 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6102#endif
6103#ifdef _SC_SCHAR_MIN
6104 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6105#endif
6106#ifdef _SC_SELECT
6107 {"SC_SELECT", _SC_SELECT},
6108#endif
6109#ifdef _SC_SEMAPHORES
6110 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6111#endif
6112#ifdef _SC_SEM_NSEMS_MAX
6113 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6114#endif
6115#ifdef _SC_SEM_VALUE_MAX
6116 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6117#endif
6118#ifdef _SC_SHARED_MEMORY_OBJECTS
6119 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6120#endif
6121#ifdef _SC_SHRT_MAX
6122 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6123#endif
6124#ifdef _SC_SHRT_MIN
6125 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6126#endif
6127#ifdef _SC_SIGQUEUE_MAX
6128 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6129#endif
6130#ifdef _SC_SIGRT_MAX
6131 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6132#endif
6133#ifdef _SC_SIGRT_MIN
6134 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6135#endif
Fred Draked86ed291999-12-15 15:34:33 +00006136#ifdef _SC_SOFTPOWER
6137 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6138#endif
Fred Drakec9680921999-12-13 16:37:25 +00006139#ifdef _SC_SPLIT_CACHE
6140 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6141#endif
6142#ifdef _SC_SSIZE_MAX
6143 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6144#endif
6145#ifdef _SC_STACK_PROT
6146 {"SC_STACK_PROT", _SC_STACK_PROT},
6147#endif
6148#ifdef _SC_STREAM_MAX
6149 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6150#endif
6151#ifdef _SC_SYNCHRONIZED_IO
6152 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6153#endif
6154#ifdef _SC_THREADS
6155 {"SC_THREADS", _SC_THREADS},
6156#endif
6157#ifdef _SC_THREAD_ATTR_STACKADDR
6158 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6159#endif
6160#ifdef _SC_THREAD_ATTR_STACKSIZE
6161 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6162#endif
6163#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6164 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6165#endif
6166#ifdef _SC_THREAD_KEYS_MAX
6167 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6168#endif
6169#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6170 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6171#endif
6172#ifdef _SC_THREAD_PRIO_INHERIT
6173 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6174#endif
6175#ifdef _SC_THREAD_PRIO_PROTECT
6176 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6177#endif
6178#ifdef _SC_THREAD_PROCESS_SHARED
6179 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6180#endif
6181#ifdef _SC_THREAD_SAFE_FUNCTIONS
6182 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6183#endif
6184#ifdef _SC_THREAD_STACK_MIN
6185 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6186#endif
6187#ifdef _SC_THREAD_THREADS_MAX
6188 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6189#endif
6190#ifdef _SC_TIMERS
6191 {"SC_TIMERS", _SC_TIMERS},
6192#endif
6193#ifdef _SC_TIMER_MAX
6194 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6195#endif
6196#ifdef _SC_TTY_NAME_MAX
6197 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6198#endif
6199#ifdef _SC_TZNAME_MAX
6200 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6201#endif
6202#ifdef _SC_T_IOV_MAX
6203 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6204#endif
6205#ifdef _SC_UCHAR_MAX
6206 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6207#endif
6208#ifdef _SC_UINT_MAX
6209 {"SC_UINT_MAX", _SC_UINT_MAX},
6210#endif
6211#ifdef _SC_UIO_MAXIOV
6212 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6213#endif
6214#ifdef _SC_ULONG_MAX
6215 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6216#endif
6217#ifdef _SC_USHRT_MAX
6218 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6219#endif
6220#ifdef _SC_VERSION
6221 {"SC_VERSION", _SC_VERSION},
6222#endif
6223#ifdef _SC_WORD_BIT
6224 {"SC_WORD_BIT", _SC_WORD_BIT},
6225#endif
6226#ifdef _SC_XBS5_ILP32_OFF32
6227 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6228#endif
6229#ifdef _SC_XBS5_ILP32_OFFBIG
6230 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6231#endif
6232#ifdef _SC_XBS5_LP64_OFF64
6233 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6234#endif
6235#ifdef _SC_XBS5_LPBIG_OFFBIG
6236 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6237#endif
6238#ifdef _SC_XOPEN_CRYPT
6239 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6240#endif
6241#ifdef _SC_XOPEN_ENH_I18N
6242 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6243#endif
6244#ifdef _SC_XOPEN_LEGACY
6245 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6246#endif
6247#ifdef _SC_XOPEN_REALTIME
6248 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6249#endif
6250#ifdef _SC_XOPEN_REALTIME_THREADS
6251 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6252#endif
6253#ifdef _SC_XOPEN_SHM
6254 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6255#endif
6256#ifdef _SC_XOPEN_UNIX
6257 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6258#endif
6259#ifdef _SC_XOPEN_VERSION
6260 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6261#endif
6262#ifdef _SC_XOPEN_XCU_VERSION
6263 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6264#endif
6265#ifdef _SC_XOPEN_XPG2
6266 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6267#endif
6268#ifdef _SC_XOPEN_XPG3
6269 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6270#endif
6271#ifdef _SC_XOPEN_XPG4
6272 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6273#endif
6274};
6275
6276static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006277conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006278{
6279 return conv_confname(arg, valuep, posix_constants_sysconf,
6280 sizeof(posix_constants_sysconf)
6281 / sizeof(struct constdef));
6282}
6283
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006284PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006285"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006286Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006287
6288static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006289posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006290{
6291 PyObject *result = NULL;
6292 int name;
6293
6294 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6295 int value;
6296
6297 errno = 0;
6298 value = sysconf(name);
6299 if (value == -1 && errno != 0)
6300 posix_error();
6301 else
6302 result = PyInt_FromLong(value);
6303 }
6304 return result;
6305}
6306#endif
6307
6308
Fred Drakebec628d1999-12-15 18:31:10 +00006309/* This code is used to ensure that the tables of configuration value names
6310 * are in sorted order as required by conv_confname(), and also to build the
6311 * the exported dictionaries that are used to publish information about the
6312 * names available on the host platform.
6313 *
6314 * Sorting the table at runtime ensures that the table is properly ordered
6315 * when used, even for platforms we're not able to test on. It also makes
6316 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006317 */
Fred Drakebec628d1999-12-15 18:31:10 +00006318
6319static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006320cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006321{
6322 const struct constdef *c1 =
6323 (const struct constdef *) v1;
6324 const struct constdef *c2 =
6325 (const struct constdef *) v2;
6326
6327 return strcmp(c1->name, c2->name);
6328}
6329
6330static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006331setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006332 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006333{
Fred Drakebec628d1999-12-15 18:31:10 +00006334 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006335 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006336
6337 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6338 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006339 if (d == NULL)
6340 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006341
Barry Warsaw3155db32000-04-13 15:20:40 +00006342 for (i=0; i < tablesize; ++i) {
6343 PyObject *o = PyInt_FromLong(table[i].value);
6344 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6345 Py_XDECREF(o);
6346 Py_DECREF(d);
6347 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006348 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006349 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006350 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006351 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006352}
6353
Fred Drakebec628d1999-12-15 18:31:10 +00006354/* Return -1 on failure, 0 on success. */
6355static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006356setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006357{
6358#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006359 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006360 sizeof(posix_constants_pathconf)
6361 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006362 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006363 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006364#endif
6365#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006366 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006367 sizeof(posix_constants_confstr)
6368 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006369 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006370 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006371#endif
6372#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006373 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006374 sizeof(posix_constants_sysconf)
6375 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006376 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006377 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006378#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006379 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006380}
Fred Draked86ed291999-12-15 15:34:33 +00006381
6382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006383PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006384"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006385Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006386in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006387
6388static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006389posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006390{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006391 abort();
6392 /*NOTREACHED*/
6393 Py_FatalError("abort() called from Python code didn't abort!");
6394 return NULL;
6395}
Fred Drakebec628d1999-12-15 18:31:10 +00006396
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006397#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006398PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006399"startfile(filepath [, operation]) - Start a file with its associated\n\
6400application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006401\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006402When \"operation\" is not specified or \"open\", this acts like\n\
6403double-clicking the file in Explorer, or giving the file name as an\n\
6404argument to the DOS \"start\" command: the file is opened with whatever\n\
6405application (if any) its extension is associated.\n\
6406When another \"operation\" is given, it specifies what should be done with\n\
6407the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006408\n\
6409startfile returns as soon as the associated application is launched.\n\
6410There is no option to wait for the application to close, and no way\n\
6411to retrieve the application's exit status.\n\
6412\n\
6413The filepath is relative to the current directory. If you want to use\n\
6414an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006415the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006416
6417static PyObject *
6418win32_startfile(PyObject *self, PyObject *args)
6419{
6420 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006421 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006422 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006423#ifdef Py_WIN_WIDE_FILENAMES
6424 if (unicode_file_names()) {
6425 PyObject *unipath, *woperation = NULL;
6426 if (!PyArg_ParseTuple(args, "U|s:startfile",
6427 &unipath, &operation)) {
6428 PyErr_Clear();
6429 goto normal;
6430 }
6431
6432
6433 if (operation) {
6434 woperation = PyUnicode_DecodeASCII(operation,
6435 strlen(operation), NULL);
6436 if (!woperation) {
6437 PyErr_Clear();
6438 operation = NULL;
6439 goto normal;
6440 }
6441 }
6442
6443 Py_BEGIN_ALLOW_THREADS
6444 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6445 PyUnicode_AS_UNICODE(unipath),
6446 NULL, NULL, SW_SHOWNORMAL);
6447 Py_END_ALLOW_THREADS
6448
6449 Py_XDECREF(woperation);
6450 if (rc <= (HINSTANCE)32) {
6451 PyObject *errval = win32_error_unicode("startfile",
6452 PyUnicode_AS_UNICODE(unipath));
6453 return errval;
6454 }
6455 Py_INCREF(Py_None);
6456 return Py_None;
6457 }
6458#endif
6459
6460normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00006461 if (!PyArg_ParseTuple(args, "et|s:startfile",
6462 Py_FileSystemDefaultEncoding, &filepath,
6463 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006464 return NULL;
6465 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006466 rc = ShellExecute((HWND)0, operation, filepath,
6467 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006468 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006469 if (rc <= (HINSTANCE)32) {
6470 PyObject *errval = win32_error("startfile", filepath);
6471 PyMem_Free(filepath);
6472 return errval;
6473 }
6474 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006475 Py_INCREF(Py_None);
6476 return Py_None;
6477}
6478#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006479
Martin v. Löwis438b5342002-12-27 10:16:42 +00006480#ifdef HAVE_GETLOADAVG
6481PyDoc_STRVAR(posix_getloadavg__doc__,
6482"getloadavg() -> (float, float, float)\n\n\
6483Return the number of processes in the system run queue averaged over\n\
6484the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6485was unobtainable");
6486
6487static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006488posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006489{
6490 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006491 if (getloadavg(loadavg, 3)!=3) {
6492 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6493 return NULL;
6494 } else
6495 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6496}
6497#endif
6498
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006499#ifdef MS_WINDOWS
6500
6501PyDoc_STRVAR(win32_urandom__doc__,
6502"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006503Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006504
6505typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6506 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6507 DWORD dwFlags );
6508typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6509 BYTE *pbBuffer );
6510
6511static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006512/* This handle is never explicitly released. Instead, the operating
6513 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006514static HCRYPTPROV hCryptProv = 0;
6515
Tim Peters4ad82172004-08-30 17:02:04 +00006516static PyObject*
6517win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006518{
Tim Petersd3115382004-08-30 17:36:46 +00006519 int howMany;
6520 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006521
Tim Peters4ad82172004-08-30 17:02:04 +00006522 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006523 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006524 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006525 if (howMany < 0)
6526 return PyErr_Format(PyExc_ValueError,
6527 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006528
Tim Peters4ad82172004-08-30 17:02:04 +00006529 if (hCryptProv == 0) {
6530 HINSTANCE hAdvAPI32 = NULL;
6531 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006532
Tim Peters4ad82172004-08-30 17:02:04 +00006533 /* Obtain handle to the DLL containing CryptoAPI
6534 This should not fail */
6535 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6536 if(hAdvAPI32 == NULL)
6537 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006538
Tim Peters4ad82172004-08-30 17:02:04 +00006539 /* Obtain pointers to the CryptoAPI functions
6540 This will fail on some early versions of Win95 */
6541 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6542 hAdvAPI32,
6543 "CryptAcquireContextA");
6544 if (pCryptAcquireContext == NULL)
6545 return PyErr_Format(PyExc_NotImplementedError,
6546 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006547
Tim Peters4ad82172004-08-30 17:02:04 +00006548 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6549 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006550 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006551 return PyErr_Format(PyExc_NotImplementedError,
6552 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006553
Tim Peters4ad82172004-08-30 17:02:04 +00006554 /* Acquire context */
6555 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6556 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6557 return win32_error("CryptAcquireContext", NULL);
6558 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006559
Tim Peters4ad82172004-08-30 17:02:04 +00006560 /* Allocate bytes */
Neal Norwitz93c56822007-08-26 07:10:06 +00006561 result = PyBytes_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00006562 if (result != NULL) {
6563 /* Get random data */
6564 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Neal Norwitz93c56822007-08-26 07:10:06 +00006565 PyBytes_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00006566 Py_DECREF(result);
6567 return win32_error("CryptGenRandom", NULL);
6568 }
Tim Peters4ad82172004-08-30 17:02:04 +00006569 }
Tim Petersd3115382004-08-30 17:36:46 +00006570 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006571}
6572#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006573
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006574PyDoc_STRVAR(device_encoding__doc__,
6575"device_encoding(fd) -> str\n\n\
6576Return a string describing the encoding of the device\n\
6577if the output is a terminal; else return None.");
6578
6579static PyObject *
6580device_encoding(PyObject *self, PyObject *args)
6581{
6582 int fd;
6583 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6584 return NULL;
6585 if (!isatty(fd)) {
6586 Py_INCREF(Py_None);
6587 return Py_None;
6588 }
6589#if defined(MS_WINDOWS) || defined(MS_WIN64)
6590 if (fd == 0) {
6591 char buf[100];
6592 sprintf(buf, "cp%d", GetConsoleCP());
6593 return PyUnicode_FromString(buf);
6594 }
6595 if (fd == 1 || fd == 2) {
6596 char buf[100];
6597 sprintf(buf, "cp%d", GetConsoleOutputCP());
6598 return PyUnicode_FromString(buf);
6599 }
6600#elif defined(CODESET)
6601 {
6602 char *codeset = nl_langinfo(CODESET);
6603 if (codeset)
6604 return PyUnicode_FromString(codeset);
6605 }
6606#endif
6607 Py_INCREF(Py_None);
6608 return Py_None;
6609}
6610
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006611#ifdef __VMS
6612/* Use openssl random routine */
6613#include <openssl/rand.h>
6614PyDoc_STRVAR(vms_urandom__doc__,
6615"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006616Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006617
6618static PyObject*
6619vms_urandom(PyObject *self, PyObject *args)
6620{
6621 int howMany;
6622 PyObject* result;
6623
6624 /* Read arguments */
6625 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6626 return NULL;
6627 if (howMany < 0)
6628 return PyErr_Format(PyExc_ValueError,
6629 "negative argument not allowed");
6630
6631 /* Allocate bytes */
Neal Norwitz93c56822007-08-26 07:10:06 +00006632 result = PyBytes_FromStringAndSize(NULL, howMany);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006633 if (result != NULL) {
6634 /* Get random data */
6635 if (RAND_pseudo_bytes((unsigned char*)
Neal Norwitz93c56822007-08-26 07:10:06 +00006636 PyBytes_AS_STRING(result),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006637 howMany) < 0) {
6638 Py_DECREF(result);
6639 return PyErr_Format(PyExc_ValueError,
6640 "RAND_pseudo_bytes");
6641 }
6642 }
6643 return result;
6644}
6645#endif
6646
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006647static PyMethodDef posix_methods[] = {
6648 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6649#ifdef HAVE_TTYNAME
6650 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6651#endif
6652 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00006653#ifdef HAVE_CHFLAGS
6654 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
6655#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006656 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006657#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006658 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006659#endif /* HAVE_CHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00006660#ifdef HAVE_LCHFLAGS
6661 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
6662#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006663#ifdef HAVE_LCHOWN
6664 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6665#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006666#ifdef HAVE_CHROOT
6667 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6668#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006669#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006670 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006671#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006672#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006673 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Neal Norwitze241ce82003-02-17 18:17:05 +00006674 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006675#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006676#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006677 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006678#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006679 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6680 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6681 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006682#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006683 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006684#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006685#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006686 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006687#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006688 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6689 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6690 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006691 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006692#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006693 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006694#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006695#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006696 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006697#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006698 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006699#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006700 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006701#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006702 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6703 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6704 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006705#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006706 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006707#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006708 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006709#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006710 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6711 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006712#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006713#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006714 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6715 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006716#if defined(PYOS_OS2)
6717 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
6718 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
6719#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00006720#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006721#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006722 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006723#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006724#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006725 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006726#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006727#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006728 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006729#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006730#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006731 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006732#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006733#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006734 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006735#endif /* HAVE_GETEGID */
6736#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006737 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006738#endif /* HAVE_GETEUID */
6739#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006740 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006741#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006742#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006743 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00006744#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006745 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006746#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006747 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006748#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006749#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00006750 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006751#endif /* HAVE_GETPPID */
6752#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006753 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006754#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006755#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00006756 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00006757#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006758#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006759 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006760#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006761#ifdef HAVE_KILLPG
6762 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6763#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006764#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006765 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006766#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00006767#ifdef MS_WINDOWS
6768 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
6769#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006770#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006771 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006772#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006773#ifdef HAVE_SETEUID
6774 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6775#endif /* HAVE_SETEUID */
6776#ifdef HAVE_SETEGID
6777 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6778#endif /* HAVE_SETEGID */
6779#ifdef HAVE_SETREUID
6780 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6781#endif /* HAVE_SETREUID */
6782#ifdef HAVE_SETREGID
6783 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6784#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006785#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006786 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006787#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006788#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006789 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006790#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006791#ifdef HAVE_GETPGID
6792 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6793#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006794#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006795 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006796#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006797#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00006798 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006799#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006800#ifdef HAVE_WAIT3
6801 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
6802#endif /* HAVE_WAIT3 */
6803#ifdef HAVE_WAIT4
6804 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
6805#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00006806#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006807 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006808#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006809#ifdef HAVE_GETSID
6810 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
6811#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006812#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00006813 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006814#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006815#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006816 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006817#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006818#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006819 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006820#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006821#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006822 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006823#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006824 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6825 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006826 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006827 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6828 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6829 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6830 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6831 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6832 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006833 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006834#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00006835 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006836#endif
6837#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006838 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006839#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006840#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006841 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6842#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006843#ifdef HAVE_DEVICE_MACROS
6844 {"major", posix_major, METH_VARARGS, posix_major__doc__},
6845 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
6846 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
6847#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006848#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006849 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006850#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006851#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006852 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006853#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006854#ifdef HAVE_UNSETENV
6855 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6856#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006857#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006858 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006859#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006860#ifdef HAVE_FCHDIR
6861 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6862#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006863#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006864 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006865#endif
6866#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006867 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006868#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006869#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006870#ifdef WCOREDUMP
6871 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6872#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006873#ifdef WIFCONTINUED
6874 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6875#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006876#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006877 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006878#endif /* WIFSTOPPED */
6879#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006880 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006881#endif /* WIFSIGNALED */
6882#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006883 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006884#endif /* WIFEXITED */
6885#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006886 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006887#endif /* WEXITSTATUS */
6888#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006889 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006890#endif /* WTERMSIG */
6891#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006892 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006893#endif /* WSTOPSIG */
6894#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00006895#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006896 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006897#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00006898#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006899 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006900#endif
Fred Drakec9680921999-12-13 16:37:25 +00006901#ifdef HAVE_CONFSTR
6902 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6903#endif
6904#ifdef HAVE_SYSCONF
6905 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6906#endif
6907#ifdef HAVE_FPATHCONF
6908 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6909#endif
6910#ifdef HAVE_PATHCONF
6911 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6912#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006913 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006914#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006915 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6916#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006917#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00006918 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00006919#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006920 #ifdef MS_WINDOWS
6921 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
6922 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006923 #ifdef __VMS
6924 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
6925 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006926 {NULL, NULL} /* Sentinel */
6927};
6928
6929
Barry Warsaw4a342091996-12-19 23:50:02 +00006930static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006931ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006932{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006933 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006934}
6935
Guido van Rossumd48f2521997-12-05 22:19:34 +00006936#if defined(PYOS_OS2)
6937/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006938static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006939{
6940 APIRET rc;
6941 ULONG values[QSV_MAX+1];
6942 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006943 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006944
6945 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00006946 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006947 Py_END_ALLOW_THREADS
6948
6949 if (rc != NO_ERROR) {
6950 os2_error(rc);
6951 return -1;
6952 }
6953
Fred Drake4d1e64b2002-04-15 19:40:07 +00006954 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6955 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6956 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6957 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6958 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6959 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6960 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006961
6962 switch (values[QSV_VERSION_MINOR]) {
6963 case 0: ver = "2.00"; break;
6964 case 10: ver = "2.10"; break;
6965 case 11: ver = "2.11"; break;
6966 case 30: ver = "3.00"; break;
6967 case 40: ver = "4.00"; break;
6968 case 50: ver = "5.00"; break;
6969 default:
Tim Peters885d4572001-11-28 20:27:42 +00006970 PyOS_snprintf(tmp, sizeof(tmp),
6971 "%d-%d", values[QSV_VERSION_MAJOR],
6972 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006973 ver = &tmp[0];
6974 }
6975
6976 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006977 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006978 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006979
6980 /* Add Indicator of Which Drive was Used to Boot the System */
6981 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6982 tmp[1] = ':';
6983 tmp[2] = '\0';
6984
Fred Drake4d1e64b2002-04-15 19:40:07 +00006985 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006986}
6987#endif
6988
Barry Warsaw4a342091996-12-19 23:50:02 +00006989static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006990all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006991{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006992#ifdef F_OK
6993 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006994#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006995#ifdef R_OK
6996 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006997#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006998#ifdef W_OK
6999 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007000#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007001#ifdef X_OK
7002 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007003#endif
Fred Drakec9680921999-12-13 16:37:25 +00007004#ifdef NGROUPS_MAX
7005 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7006#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007007#ifdef TMP_MAX
7008 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7009#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007010#ifdef WCONTINUED
7011 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7012#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007013#ifdef WNOHANG
7014 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007015#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007016#ifdef WUNTRACED
7017 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7018#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007019#ifdef O_RDONLY
7020 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7021#endif
7022#ifdef O_WRONLY
7023 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7024#endif
7025#ifdef O_RDWR
7026 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7027#endif
7028#ifdef O_NDELAY
7029 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7030#endif
7031#ifdef O_NONBLOCK
7032 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7033#endif
7034#ifdef O_APPEND
7035 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7036#endif
7037#ifdef O_DSYNC
7038 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7039#endif
7040#ifdef O_RSYNC
7041 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7042#endif
7043#ifdef O_SYNC
7044 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7045#endif
7046#ifdef O_NOCTTY
7047 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7048#endif
7049#ifdef O_CREAT
7050 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7051#endif
7052#ifdef O_EXCL
7053 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7054#endif
7055#ifdef O_TRUNC
7056 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7057#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007058#ifdef O_BINARY
7059 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7060#endif
7061#ifdef O_TEXT
7062 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7063#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007064#ifdef O_LARGEFILE
7065 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7066#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007067#ifdef O_SHLOCK
7068 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7069#endif
7070#ifdef O_EXLOCK
7071 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7072#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007073
Tim Peters5aa91602002-01-30 05:46:57 +00007074/* MS Windows */
7075#ifdef O_NOINHERIT
7076 /* Don't inherit in child processes. */
7077 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7078#endif
7079#ifdef _O_SHORT_LIVED
7080 /* Optimize for short life (keep in memory). */
7081 /* MS forgot to define this one with a non-underscore form too. */
7082 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7083#endif
7084#ifdef O_TEMPORARY
7085 /* Automatically delete when last handle is closed. */
7086 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7087#endif
7088#ifdef O_RANDOM
7089 /* Optimize for random access. */
7090 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7091#endif
7092#ifdef O_SEQUENTIAL
7093 /* Optimize for sequential access. */
7094 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7095#endif
7096
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007097/* GNU extensions. */
7098#ifdef O_DIRECT
7099 /* Direct disk access. */
7100 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7101#endif
7102#ifdef O_DIRECTORY
7103 /* Must be a directory. */
7104 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7105#endif
7106#ifdef O_NOFOLLOW
7107 /* Do not follow links. */
7108 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7109#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007110
Barry Warsaw5676bd12003-01-07 20:57:09 +00007111 /* These come from sysexits.h */
7112#ifdef EX_OK
7113 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007114#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007115#ifdef EX_USAGE
7116 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007117#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007118#ifdef EX_DATAERR
7119 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007120#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007121#ifdef EX_NOINPUT
7122 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007123#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007124#ifdef EX_NOUSER
7125 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007126#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007127#ifdef EX_NOHOST
7128 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007129#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007130#ifdef EX_UNAVAILABLE
7131 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007132#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007133#ifdef EX_SOFTWARE
7134 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007135#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007136#ifdef EX_OSERR
7137 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007138#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007139#ifdef EX_OSFILE
7140 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007141#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007142#ifdef EX_CANTCREAT
7143 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007144#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007145#ifdef EX_IOERR
7146 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007147#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007148#ifdef EX_TEMPFAIL
7149 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007150#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007151#ifdef EX_PROTOCOL
7152 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007153#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007154#ifdef EX_NOPERM
7155 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007156#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007157#ifdef EX_CONFIG
7158 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007159#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007160#ifdef EX_NOTFOUND
7161 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007162#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007163
Guido van Rossum246bc171999-02-01 23:54:31 +00007164#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007165#if defined(PYOS_OS2) && defined(PYCC_GCC)
7166 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7167 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7168 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7169 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7170 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7171 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7172 if (ins(d, "P_PM", (long)P_PM)) return -1;
7173 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7174 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7175 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7176 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7177 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7178 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7179 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7180 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7181 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7182 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7183 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7184 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7185 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7186#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007187 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7188 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7189 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7190 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7191 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007192#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007193#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007194
Guido van Rossumd48f2521997-12-05 22:19:34 +00007195#if defined(PYOS_OS2)
7196 if (insertvalues(d)) return -1;
7197#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007198 return 0;
7199}
7200
7201
Tim Peters5aa91602002-01-30 05:46:57 +00007202#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007203#define INITFUNC initnt
7204#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007205
7206#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007207#define INITFUNC initos2
7208#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007209
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007210#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007211#define INITFUNC initposix
7212#define MODNAME "posix"
7213#endif
7214
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007215PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007216INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007217{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007218 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007219
Fred Drake4d1e64b2002-04-15 19:40:07 +00007220 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007221 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007222 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007223 if (m == NULL)
7224 return;
Tim Peters5aa91602002-01-30 05:46:57 +00007225
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007226 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007227 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007228 Py_XINCREF(v);
7229 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007230 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007231 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007232
Fred Drake4d1e64b2002-04-15 19:40:07 +00007233 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007234 return;
7235
Fred Drake4d1e64b2002-04-15 19:40:07 +00007236 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007237 return;
7238
Fred Drake4d1e64b2002-04-15 19:40:07 +00007239 Py_INCREF(PyExc_OSError);
7240 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007241
Guido van Rossumb3d39562000-01-31 18:41:26 +00007242#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007243 if (posix_putenv_garbage == NULL)
7244 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007245#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007246
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007247 if (!initialized) {
7248 stat_result_desc.name = MODNAME ".stat_result";
7249 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7250 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7251 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7252 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7253 structseq_new = StatResultType.tp_new;
7254 StatResultType.tp_new = statresult_new;
7255
7256 statvfs_result_desc.name = MODNAME ".statvfs_result";
7257 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
7258 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007259 Py_INCREF((PyObject*) &StatResultType);
7260 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007261 Py_INCREF((PyObject*) &StatVFSResultType);
7262 PyModule_AddObject(m, "statvfs_result",
7263 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007264 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007265
7266#ifdef __APPLE__
7267 /*
7268 * Step 2 of weak-linking support on Mac OS X.
7269 *
7270 * The code below removes functions that are not available on the
7271 * currently active platform.
7272 *
7273 * This block allow one to use a python binary that was build on
7274 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7275 * OSX 10.4.
7276 */
7277#ifdef HAVE_FSTATVFS
7278 if (fstatvfs == NULL) {
7279 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
7280 return;
7281 }
7282 }
7283#endif /* HAVE_FSTATVFS */
7284
7285#ifdef HAVE_STATVFS
7286 if (statvfs == NULL) {
7287 if (PyObject_DelAttrString(m, "statvfs") == -1) {
7288 return;
7289 }
7290 }
7291#endif /* HAVE_STATVFS */
7292
7293# ifdef HAVE_LCHOWN
7294 if (lchown == NULL) {
7295 if (PyObject_DelAttrString(m, "lchown") == -1) {
7296 return;
7297 }
7298 }
7299#endif /* HAVE_LCHOWN */
7300
7301
7302#endif /* __APPLE__ */
7303
Guido van Rossumb6775db1994-08-01 11:34:53 +00007304}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007305
7306#ifdef __cplusplus
7307}
7308#endif