blob: 71a102c7c28a72e9601a9e54651d0f70144263be [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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000019#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000020# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000021#endif /* defined(__VMS) */
22
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000024"This module provides access to operating system functionality that is\n\
25standardized by the C Standard and the POSIX standard (a thinly\n\
26disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000029#ifndef Py_USING_UNICODE
30/* This is used in signatures of functions. */
31#define Py_UNICODE void
32#endif
33
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000034#if defined(PYOS_OS2)
35#define INCL_DOS
36#define INCL_DOSERRORS
37#define INCL_DOSPROCESS
38#define INCL_NOPMAPI
39#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000040#if defined(PYCC_GCC)
41#include <ctype.h>
42#include <io.h>
43#include <stdio.h>
44#include <process.h>
45#include "osdefs.h"
46#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000047#endif
48
Guido van Rossumb6775db1994-08-01 11:34:53 +000049#include <sys/types.h>
50#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000051
Guido van Rossum36bc6801995-06-14 22:54:23 +000052#ifdef HAVE_SYS_WAIT_H
53#include <sys/wait.h> /* For WNOHANG */
54#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000055
Guido van Rossuma376cc51996-12-05 23:43:35 +000056#ifdef HAVE_SIGNAL_H
57#include <signal.h>
58#endif
59
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#ifdef HAVE_FCNTL_H
61#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000062#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000063
Guido van Rossuma6535fd2001-10-18 19:44:10 +000064#ifdef HAVE_GRP_H
65#include <grp.h>
66#endif
67
Barry Warsaw5676bd12003-01-07 20:57:09 +000068#ifdef HAVE_SYSEXITS_H
69#include <sysexits.h>
70#endif /* HAVE_SYSEXITS_H */
71
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000073/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000074#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000075#include <process.h>
76#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000077#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000078#define HAVE_GETCWD 1
79#define HAVE_OPENDIR 1
80#define HAVE_SYSTEM 1
81#if defined(__OS2__)
82#define HAVE_EXECV 1
83#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000084#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000085#include <process.h>
86#else
87#ifdef __BORLANDC__ /* Borland compiler */
88#define HAVE_EXECV 1
89#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000090#define HAVE_OPENDIR 1
91#define HAVE_PIPE 1
92#define HAVE_POPEN 1
93#define HAVE_SYSTEM 1
94#define HAVE_WAIT 1
95#else
96#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000097#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +000098#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099#define HAVE_EXECV 1
100#define HAVE_PIPE 1
101#define HAVE_POPEN 1
102#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000103#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000104#define HAVE_FSYNC 1
105#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000106#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000107#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
108/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000109#else /* all other compilers */
110/* Unix functions that the configure script doesn't check for */
111#define HAVE_EXECV 1
112#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000113#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
114#define HAVE_FORK1 1
115#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000116#define HAVE_GETCWD 1
117#define HAVE_GETEGID 1
118#define HAVE_GETEUID 1
119#define HAVE_GETGID 1
120#define HAVE_GETPPID 1
121#define HAVE_GETUID 1
122#define HAVE_KILL 1
123#define HAVE_OPENDIR 1
124#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000125#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000127#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128#define HAVE_SYSTEM 1
129#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000130#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000131#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000132#endif /* _MSC_VER */
133#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000134#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000135#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000136
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000138
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000139#if defined(__sgi)&&_COMPILER_VERSION>=700
140/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
141 (default) */
142extern char *ctermid_r(char *);
143#endif
144
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000145#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000147extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000149#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000150extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
155#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000156extern int chdir(char *);
157extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000158#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000159extern int chdir(const char *);
160extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000161#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000162#ifdef __BORLANDC__
163extern int chmod(const char *, int);
164#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000165extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000166#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int chown(const char *, uid_t, gid_t);
168extern char *getcwd(char *, int);
169extern char *strerror(int);
170extern int link(const char *, const char *);
171extern int rename(const char *, const char *);
172extern int stat(const char *, struct stat *);
173extern int unlink(const char *);
174extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000176extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000177#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000180#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000182
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184
Guido van Rossumb6775db1994-08-01 11:34:53 +0000185#ifdef HAVE_UTIME_H
186#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000187#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000188
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000189#ifdef HAVE_SYS_UTIME_H
190#include <sys/utime.h>
191#define HAVE_UTIME_H /* pretend we do for the rest of this file */
192#endif /* HAVE_SYS_UTIME_H */
193
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194#ifdef HAVE_SYS_TIMES_H
195#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000196#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000197
198#ifdef HAVE_SYS_PARAM_H
199#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000200#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201
202#ifdef HAVE_SYS_UTSNAME_H
203#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000204#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#define NAMLEN(dirent) strlen((dirent)->d_name)
209#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000210#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000211#include <direct.h>
212#define NAMLEN(dirent) strlen((dirent)->d_name)
213#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000217#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000219#endif
220#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000222#endif
223#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000225#endif
226#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229#include <direct.h>
230#include <io.h>
231#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000232#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000233#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000235#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000237#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
Guido van Rossumd48f2521997-12-05 22:19:34 +0000240#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000242#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243
Tim Petersbc2e10e2002-03-03 23:17:02 +0000244#ifndef MAXPATHLEN
245#define MAXPATHLEN 1024
246#endif /* MAXPATHLEN */
247
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000248#ifdef UNION_WAIT
249/* Emulate some macros on systems that have a union instead of macros */
250
251#ifndef WIFEXITED
252#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
253#endif
254
255#ifndef WEXITSTATUS
256#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
257#endif
258
259#ifndef WTERMSIG
260#define WTERMSIG(u_wait) ((u_wait).w_termsig)
261#endif
262
263#endif /* UNION_WAIT */
264
Greg Wardb48bc172000-03-01 21:51:56 +0000265/* Don't use the "_r" form if we don't need it (also, won't have a
266 prototype for it, at least on Solaris -- maybe others as well?). */
267#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
268#define USE_CTERMID_R
269#endif
270
271#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
272#define USE_TMPNAM_R
273#endif
274
Fred Drake699f3522000-06-29 21:12:41 +0000275/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000276#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000277#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000278# define STAT _stati64
279# define FSTAT _fstati64
280# define STRUCT_STAT struct _stati64
281#else
282# define STAT stat
283# define FSTAT fstat
284# define STRUCT_STAT struct stat
285#endif
286
Tim Peters11b23062003-04-23 02:39:17 +0000287#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000288#include <sys/mkdev.h>
289#else
290#if defined(MAJOR_IN_SYSMACROS)
291#include <sys/sysmacros.h>
292#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000293#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
294#include <sys/mkdev.h>
295#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000296#endif
Fred Drake699f3522000-06-29 21:12:41 +0000297
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000299#ifdef WITH_NEXT_FRAMEWORK
300/* On Darwin/MacOSX a shared library or framework has no access to
301** environ directly, we must obtain it with _NSGetEnviron().
302*/
303#include <crt_externs.h>
304static char **environ;
305#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000307#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308
Barry Warsaw53699e91996-12-10 23:23:01 +0000309static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000310convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311{
Barry Warsaw53699e91996-12-10 23:23:01 +0000312 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000314 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315 if (d == NULL)
316 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000317#ifdef WITH_NEXT_FRAMEWORK
318 if (environ == NULL)
319 environ = *_NSGetEnviron();
320#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000321 if (environ == NULL)
322 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000323 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000325 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000326 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000327 char *p = strchr(*e, '=');
328 if (p == NULL)
329 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000330 k = PyString_FromStringAndSize(*e, (int)(p-*e));
331 if (k == NULL) {
332 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000334 }
335 v = PyString_FromString(p+1);
336 if (v == NULL) {
337 PyErr_Clear();
338 Py_DECREF(k);
339 continue;
340 }
341 if (PyDict_GetItem(d, k) == NULL) {
342 if (PyDict_SetItem(d, k, v) != 0)
343 PyErr_Clear();
344 }
345 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000346 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000348#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000349 {
350 APIRET rc;
351 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
352
353 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000354 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000355 PyObject *v = PyString_FromString(buffer);
356 PyDict_SetItemString(d, "BEGINLIBPATH", v);
357 Py_DECREF(v);
358 }
359 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
360 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
361 PyObject *v = PyString_FromString(buffer);
362 PyDict_SetItemString(d, "ENDLIBPATH", v);
363 Py_DECREF(v);
364 }
365 }
366#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000367 return d;
368}
369
370
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000371/* Set a POSIX-specific error from errno, and return NULL */
372
Barry Warsawd58d7641998-07-23 16:14:40 +0000373static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000374posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000375{
Barry Warsawca74da41999-02-09 19:31:45 +0000376 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377}
Barry Warsawd58d7641998-07-23 16:14:40 +0000378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000379posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000380{
Barry Warsawca74da41999-02-09 19:31:45 +0000381 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000382}
383
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000384#ifdef Py_WIN_WIDE_FILENAMES
385static PyObject *
386posix_error_with_unicode_filename(Py_UNICODE* name)
387{
388 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
389}
390#endif /* Py_WIN_WIDE_FILENAMES */
391
392
Mark Hammondef8b6542001-05-13 08:04:26 +0000393static PyObject *
394posix_error_with_allocated_filename(char* name)
395{
396 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
397 PyMem_Free(name);
398 return rc;
399}
400
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000401#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000402static PyObject *
403win32_error(char* function, char* filename)
404{
Mark Hammond33a6da92000-08-15 00:46:38 +0000405 /* XXX We should pass the function name along in the future.
406 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000407 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000408 Windows error object, which is non-trivial.
409 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000410 errno = GetLastError();
411 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000412 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000413 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000414 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000415}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000416
417#ifdef Py_WIN_WIDE_FILENAMES
418static PyObject *
419win32_error_unicode(char* function, Py_UNICODE* filename)
420{
421 /* XXX - see win32_error for comments on 'function' */
422 errno = GetLastError();
423 if (filename)
424 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
425 else
426 return PyErr_SetFromWindowsErr(errno);
427}
428
429static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
430{
431 /* XXX Perhaps we should make this API an alias of
432 PyObject_Unicode() instead ?! */
433 if (PyUnicode_CheckExact(obj)) {
434 Py_INCREF(obj);
435 return obj;
436 }
437 if (PyUnicode_Check(obj)) {
438 /* For a Unicode subtype that's not a Unicode object,
439 return a true Unicode object with the same data. */
440 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
441 PyUnicode_GET_SIZE(obj));
442 }
Tim Peters11b23062003-04-23 02:39:17 +0000443 return PyUnicode_FromEncodedObject(obj,
444 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000445 "strict");
446}
447
448#endif /* Py_WIN_WIDE_FILENAMES */
449
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000450#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000451
Guido van Rossumd48f2521997-12-05 22:19:34 +0000452#if defined(PYOS_OS2)
453/**********************************************************************
454 * Helper Function to Trim and Format OS/2 Messages
455 **********************************************************************/
456 static void
457os2_formatmsg(char *msgbuf, int msglen, char *reason)
458{
459 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
460
461 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
462 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
463
464 while (lastc > msgbuf && isspace(*lastc))
465 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
466 }
467
468 /* Add Optional Reason Text */
469 if (reason) {
470 strcat(msgbuf, " : ");
471 strcat(msgbuf, reason);
472 }
473}
474
475/**********************************************************************
476 * Decode an OS/2 Operating System Error Code
477 *
478 * A convenience function to lookup an OS/2 error code and return a
479 * text message we can use to raise a Python exception.
480 *
481 * Notes:
482 * The messages for errors returned from the OS/2 kernel reside in
483 * the file OSO001.MSG in the \OS2 directory hierarchy.
484 *
485 **********************************************************************/
486 static char *
487os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
488{
489 APIRET rc;
490 ULONG msglen;
491
492 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
493 Py_BEGIN_ALLOW_THREADS
494 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
495 errorcode, "oso001.msg", &msglen);
496 Py_END_ALLOW_THREADS
497
498 if (rc == NO_ERROR)
499 os2_formatmsg(msgbuf, msglen, reason);
500 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000501 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000502 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000503
504 return msgbuf;
505}
506
507/* Set an OS/2-specific error and return NULL. OS/2 kernel
508 errors are not in a global variable e.g. 'errno' nor are
509 they congruent with posix error numbers. */
510
511static PyObject * os2_error(int code)
512{
513 char text[1024];
514 PyObject *v;
515
516 os2_strerror(text, sizeof(text), code, "");
517
518 v = Py_BuildValue("(is)", code, text);
519 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000520 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000521 Py_DECREF(v);
522 }
523 return NULL; /* Signal to Python that an Exception is Pending */
524}
525
526#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000527
528/* POSIX generic methods */
529
Barry Warsaw53699e91996-12-10 23:23:01 +0000530static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000531posix_fildes(PyObject *fdobj, int (*func)(int))
532{
533 int fd;
534 int res;
535 fd = PyObject_AsFileDescriptor(fdobj);
536 if (fd < 0)
537 return NULL;
538 Py_BEGIN_ALLOW_THREADS
539 res = (*func)(fd);
540 Py_END_ALLOW_THREADS
541 if (res < 0)
542 return posix_error();
543 Py_INCREF(Py_None);
544 return Py_None;
545}
Guido van Rossum21142a01999-01-08 21:05:37 +0000546
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000547#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000548static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000549unicode_file_names(void)
550{
551 static int canusewide = -1;
552 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000553 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000554 the Windows NT family. */
555 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
556 }
557 return canusewide;
558}
559#endif
Tim Peters11b23062003-04-23 02:39:17 +0000560
Guido van Rossum21142a01999-01-08 21:05:37 +0000561static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000562posix_1str(PyObject *args, char *format, int (*func)(const char*),
563 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000564{
Mark Hammondef8b6542001-05-13 08:04:26 +0000565 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000566 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000567#ifdef Py_WIN_WIDE_FILENAMES
568 if (unicode_file_names()) {
569 PyUnicodeObject *po;
570 if (PyArg_ParseTuple(args, wformat, &po)) {
571 Py_BEGIN_ALLOW_THREADS
572 /* PyUnicode_AS_UNICODE OK without thread
573 lock as it is a simple dereference. */
574 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
575 Py_END_ALLOW_THREADS
576 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000577 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000578 Py_INCREF(Py_None);
579 return Py_None;
580 }
581 /* Drop the argument parsing error as narrow
582 strings are also valid. */
583 PyErr_Clear();
584 }
585#else
586 /* Platforms that don't support Unicode filenames
587 shouldn't be passing these extra params */
588 assert(wformat==NULL && wfunc == NULL);
589#endif
590
Tim Peters5aa91602002-01-30 05:46:57 +0000591 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000592 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000593 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000594 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000595 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000596 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000597 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000598 return posix_error_with_allocated_filename(path1);
599 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000600 Py_INCREF(Py_None);
601 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000602}
603
Barry Warsaw53699e91996-12-10 23:23:01 +0000604static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000605posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000606 char *format,
607 int (*func)(const char *, const char *),
608 char *wformat,
609 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000610{
Mark Hammondef8b6542001-05-13 08:04:26 +0000611 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000612 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000613#ifdef Py_WIN_WIDE_FILENAMES
614 if (unicode_file_names()) {
615 PyObject *po1;
616 PyObject *po2;
617 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
618 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
619 PyObject *wpath1;
620 PyObject *wpath2;
621 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
622 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
623 if (!wpath1 || !wpath2) {
624 Py_XDECREF(wpath1);
625 Py_XDECREF(wpath2);
626 return NULL;
627 }
628 Py_BEGIN_ALLOW_THREADS
629 /* PyUnicode_AS_UNICODE OK without thread
630 lock as it is a simple dereference. */
631 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
632 PyUnicode_AS_UNICODE(wpath2));
633 Py_END_ALLOW_THREADS
634 Py_XDECREF(wpath1);
635 Py_XDECREF(wpath2);
636 if (res != 0)
637 return posix_error();
638 Py_INCREF(Py_None);
639 return Py_None;
640 }
641 /* Else flow through as neither is Unicode. */
642 }
643 /* Drop the argument parsing error as narrow
644 strings are also valid. */
645 PyErr_Clear();
646 }
647#else
648 /* Platforms that don't support Unicode filenames
649 shouldn't be passing these extra params */
650 assert(wformat==NULL && wfunc == NULL);
651#endif
652
Mark Hammondef8b6542001-05-13 08:04:26 +0000653 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000654 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000655 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000656 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000657 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000658 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000659 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000660 PyMem_Free(path1);
661 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000662 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000663 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000665 Py_INCREF(Py_None);
666 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000667}
668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000669PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000670"stat_result: Result from stat or lstat.\n\n\
671This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000672 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000673or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
674\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000675Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000676they are available as attributes only.\n\
677\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000678See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000679
680static PyStructSequence_Field stat_result_fields[] = {
681 {"st_mode", "protection bits"},
682 {"st_ino", "inode"},
683 {"st_dev", "device"},
684 {"st_nlink", "number of hard links"},
685 {"st_uid", "user ID of owner"},
686 {"st_gid", "group ID of owner"},
687 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000688 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
689 {NULL, "integer time of last access"},
690 {NULL, "integer time of last modification"},
691 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000692 {"st_atime", "time of last access"},
693 {"st_mtime", "time of last modification"},
694 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000695#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000696 {"st_blksize", "blocksize for filesystem I/O"},
697#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000698#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000699 {"st_blocks", "number of blocks allocated"},
700#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000701#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000702 {"st_rdev", "device type (if inode device)"},
703#endif
704 {0}
705};
706
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000707#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000708#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000709#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000710#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000711#endif
712
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000713#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000714#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
715#else
716#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
717#endif
718
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000719#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000720#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
721#else
722#define ST_RDEV_IDX ST_BLOCKS_IDX
723#endif
724
725static PyStructSequence_Desc stat_result_desc = {
726 "stat_result", /* name */
727 stat_result__doc__, /* doc */
728 stat_result_fields,
729 10
730};
731
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000732PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000733"statvfs_result: Result from statvfs or fstatvfs.\n\n\
734This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000735 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000736or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000737\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000738See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000739
740static PyStructSequence_Field statvfs_result_fields[] = {
741 {"f_bsize", },
742 {"f_frsize", },
743 {"f_blocks", },
744 {"f_bfree", },
745 {"f_bavail", },
746 {"f_files", },
747 {"f_ffree", },
748 {"f_favail", },
749 {"f_flag", },
750 {"f_namemax",},
751 {0}
752};
753
754static PyStructSequence_Desc statvfs_result_desc = {
755 "statvfs_result", /* name */
756 statvfs_result__doc__, /* doc */
757 statvfs_result_fields,
758 10
759};
760
761static PyTypeObject StatResultType;
762static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000763static newfunc structseq_new;
764
765static PyObject *
766statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
767{
768 PyStructSequence *result;
769 int i;
770
771 result = (PyStructSequence*)structseq_new(type, args, kwds);
772 if (!result)
773 return NULL;
774 /* If we have been initialized from a tuple,
775 st_?time might be set to None. Initialize it
776 from the int slots. */
777 for (i = 7; i <= 9; i++) {
778 if (result->ob_item[i+3] == Py_None) {
779 Py_DECREF(Py_None);
780 Py_INCREF(result->ob_item[i]);
781 result->ob_item[i+3] = result->ob_item[i];
782 }
783 }
784 return (PyObject*)result;
785}
786
787
788
789/* If true, st_?time is float. */
790static int _stat_float_times = 0;
791
792PyDoc_STRVAR(stat_float_times__doc__,
793"stat_float_times([newval]) -> oldval\n\n\
794Determine whether os.[lf]stat represents time stamps as float objects.\n\
795If newval is True, future calls to stat() return floats, if it is False,\n\
796future calls return ints. \n\
797If newval is omitted, return the current setting.\n");
798
799static PyObject*
800stat_float_times(PyObject* self, PyObject *args)
801{
802 int newval = -1;
803 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
804 return NULL;
805 if (newval == -1)
806 /* Return old value */
807 return PyBool_FromLong(_stat_float_times);
808 _stat_float_times = newval;
809 Py_INCREF(Py_None);
810 return Py_None;
811}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000812
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000813static void
814fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
815{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000816 PyObject *fval,*ival;
817#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000818 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000819#else
820 ival = PyInt_FromLong((long)sec);
821#endif
822 if (_stat_float_times) {
823 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
824 } else {
825 fval = ival;
826 Py_INCREF(fval);
827 }
828 PyStructSequence_SET_ITEM(v, index, ival);
829 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000830}
831
Tim Peters5aa91602002-01-30 05:46:57 +0000832/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000833 (used by posix_stat() and posix_fstat()) */
834static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000835_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000836{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000837 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000838 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000839 if (v == NULL)
840 return NULL;
841
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000842 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000843#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000844 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000845 PyLong_FromLongLong((PY_LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000846#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000847 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000848#endif
849#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000850 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000851 PyLong_FromLongLong((PY_LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000852#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000853 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000854#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000855 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
856 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
857 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000858#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000859 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000860 PyLong_FromLongLong((PY_LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000861#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000862 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000863#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000864
865#ifdef HAVE_STAT_TV_NSEC
866 ansec = st.st_atim.tv_nsec;
867 mnsec = st.st_mtim.tv_nsec;
868 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000869#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000870 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000871#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000872 fill_time(v, 7, st.st_atime, ansec);
873 fill_time(v, 8, st.st_mtime, mnsec);
874 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000875
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000876#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000877 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000878 PyInt_FromLong((long)st.st_blksize));
879#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000880#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000881 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000882 PyInt_FromLong((long)st.st_blocks));
883#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000884#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000885 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
886 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000887#endif
888
889 if (PyErr_Occurred()) {
890 Py_DECREF(v);
891 return NULL;
892 }
893
894 return v;
895}
896
Barry Warsaw53699e91996-12-10 23:23:01 +0000897static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000898posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000899 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000900#ifdef __VMS
901 int (*statfunc)(const char *, STRUCT_STAT *, ...),
902#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000903 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000904#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000905 char *wformat,
906 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000907{
Fred Drake699f3522000-06-29 21:12:41 +0000908 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000909 char *path = NULL; /* pass this to stat; do not free() it */
910 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000911 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000912
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000913#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000914 int pathlen;
915 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000916#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000917
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000918
919#ifdef Py_WIN_WIDE_FILENAMES
920 /* If on wide-character-capable OS see if argument
921 is Unicode and if so use wide API. */
922 if (unicode_file_names()) {
923 PyUnicodeObject *po;
924 if (PyArg_ParseTuple(args, wformat, &po)) {
925 Py_UNICODE wpath[MAX_PATH+1];
926 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
927 /* the library call can blow up if the file name is too long! */
928 if (pathlen > MAX_PATH) {
929 errno = ENAMETOOLONG;
930 return posix_error();
931 }
932 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
933 /* Remove trailing slash or backslash, unless it's the current
934 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
935 */
936 if (pathlen > 0 &&
937 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
938 /* It does end with a slash -- exempt the root drive cases. */
939 /* XXX UNC root drives should also be exempted? */
940 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
941 /* leave it alone */;
942 else {
943 /* nuke the trailing backslash */
944 wpath[pathlen-1] = L'\0';
945 }
946 }
947 Py_BEGIN_ALLOW_THREADS
948 /* PyUnicode_AS_UNICODE result OK without
949 thread lock as it is a simple dereference. */
950 res = wstatfunc(wpath, &st);
951 Py_END_ALLOW_THREADS
952 if (res != 0)
953 return posix_error_with_unicode_filename(wpath);
954 return _pystat_fromstructstat(st);
955 }
956 /* Drop the argument parsing error as narrow strings
957 are also valid. */
958 PyErr_Clear();
959 }
960#endif
961
Tim Peters5aa91602002-01-30 05:46:57 +0000962 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000963 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000964 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000965 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000966
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000967#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000968 pathlen = strlen(path);
969 /* the library call can blow up if the file name is too long! */
970 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000971 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000972 errno = ENAMETOOLONG;
973 return posix_error();
974 }
975
Tim Peters500bd032001-12-19 19:05:01 +0000976 /* Remove trailing slash or backslash, unless it's the current
977 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
978 */
979 if (pathlen > 0 &&
980 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
981 /* It does end with a slash -- exempt the root drive cases. */
982 /* XXX UNC root drives should also be exempted? */
983 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
984 /* leave it alone */;
985 else {
986 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000987 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000988 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000989 path = pathcopy;
990 }
991 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000992#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000993
Barry Warsaw53699e91996-12-10 23:23:01 +0000994 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000995 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000996 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000997 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000998 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000999
Tim Peters500bd032001-12-19 19:05:01 +00001000 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001001 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001002}
1003
1004
1005/* POSIX methods */
1006
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001007PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001008"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001009Use the real uid/gid to test for access to a path. Note that most\n\
1010operations will use the effective uid/gid, therefore this routine can\n\
1011be used in a suid/sgid environment to test if the invoking user has the\n\
1012specified access to the path. The mode argument can be F_OK to test\n\
1013existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001014
1015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001016posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001017{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001018 char *path;
1019 int mode;
1020 int res;
1021
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001022#ifdef Py_WIN_WIDE_FILENAMES
1023 if (unicode_file_names()) {
1024 PyUnicodeObject *po;
1025 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1026 Py_BEGIN_ALLOW_THREADS
1027 /* PyUnicode_AS_UNICODE OK without thread lock as
1028 it is a simple dereference. */
1029 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1030 Py_END_ALLOW_THREADS
1031 return(PyBool_FromLong(res == 0));
1032 }
1033 /* Drop the argument parsing error as narrow strings
1034 are also valid. */
1035 PyErr_Clear();
1036 }
1037#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001038 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001039 return NULL;
1040 Py_BEGIN_ALLOW_THREADS
1041 res = access(path, mode);
1042 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001043 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001044}
1045
Guido van Rossumd371ff11999-01-25 16:12:23 +00001046#ifndef F_OK
1047#define F_OK 0
1048#endif
1049#ifndef R_OK
1050#define R_OK 4
1051#endif
1052#ifndef W_OK
1053#define W_OK 2
1054#endif
1055#ifndef X_OK
1056#define X_OK 1
1057#endif
1058
1059#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001060PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001061"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001062Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001063
1064static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001065posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001066{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001067 int id;
1068 char *ret;
1069
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001070 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001071 return NULL;
1072
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001073#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001074 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001075 if (id == 0) {
1076 ret = ttyname();
1077 }
1078 else {
1079 ret = NULL;
1080 }
1081#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001082 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001083#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001084 if (ret == NULL)
1085 return(posix_error());
1086 return(PyString_FromString(ret));
1087}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001088#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001089
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001090#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001091PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001092"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001093Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001094
1095static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001096posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001097{
1098 char *ret;
1099 char buffer[L_ctermid];
1100
Greg Wardb48bc172000-03-01 21:51:56 +00001101#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001102 ret = ctermid_r(buffer);
1103#else
1104 ret = ctermid(buffer);
1105#endif
1106 if (ret == NULL)
1107 return(posix_error());
1108 return(PyString_FromString(buffer));
1109}
1110#endif
1111
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001112PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001113"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001114Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001115
Barry Warsaw53699e91996-12-10 23:23:01 +00001116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001117posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001118{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001119#ifdef MS_WINDOWS
1120 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1121#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1122 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001123#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001124 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001125 NULL, NULL);
1126#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001127 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001128#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001129}
1130
Fred Drake4d1e64b2002-04-15 19:40:07 +00001131#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001132PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001133"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001134Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001135opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001136
1137static PyObject *
1138posix_fchdir(PyObject *self, PyObject *fdobj)
1139{
1140 return posix_fildes(fdobj, fchdir);
1141}
1142#endif /* HAVE_FCHDIR */
1143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001145PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001146"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001147Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001148
Barry Warsaw53699e91996-12-10 23:23:01 +00001149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001150posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001151{
Mark Hammondef8b6542001-05-13 08:04:26 +00001152 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001153 int i;
1154 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001155#ifdef Py_WIN_WIDE_FILENAMES
1156 if (unicode_file_names()) {
1157 PyUnicodeObject *po;
1158 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1159 Py_BEGIN_ALLOW_THREADS
1160 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1161 Py_END_ALLOW_THREADS
1162 if (res < 0)
1163 return posix_error_with_unicode_filename(
1164 PyUnicode_AS_UNICODE(po));
1165 Py_INCREF(Py_None);
1166 return Py_None;
1167 }
1168 /* Drop the argument parsing error as narrow strings
1169 are also valid. */
1170 PyErr_Clear();
1171 }
1172#endif /* Py_WIN_WIDE_FILENAMES */
1173 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001174 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001175 return NULL;
1176 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001177 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001178 Py_END_ALLOW_THREADS
1179 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001180 return posix_error_with_allocated_filename(path);
1181 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001182 Py_INCREF(Py_None);
1183 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184}
1185
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001186
Martin v. Löwis244edc82001-10-04 22:44:26 +00001187#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001188PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001189"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001190Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001191
1192static PyObject *
1193posix_chroot(PyObject *self, PyObject *args)
1194{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001195 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001196}
1197#endif
1198
Guido van Rossum21142a01999-01-08 21:05:37 +00001199#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001200PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001201"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001202force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001203
1204static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001205posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001206{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001207 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001208}
1209#endif /* HAVE_FSYNC */
1210
1211#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001212
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001213#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001214extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1215#endif
1216
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001217PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001218"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001219force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001220 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001221
1222static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001223posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001224{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001225 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001226}
1227#endif /* HAVE_FDATASYNC */
1228
1229
Fredrik Lundh10723342000-07-10 16:38:09 +00001230#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001231PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001232"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001233Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001234
Barry Warsaw53699e91996-12-10 23:23:01 +00001235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001236posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001237{
Mark Hammondef8b6542001-05-13 08:04:26 +00001238 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001239 int uid, gid;
1240 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001241 if (!PyArg_ParseTuple(args, "etii:chown",
1242 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001243 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001244 return NULL;
1245 Py_BEGIN_ALLOW_THREADS
1246 res = chown(path, (uid_t) uid, (gid_t) gid);
1247 Py_END_ALLOW_THREADS
1248 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001249 return posix_error_with_allocated_filename(path);
1250 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001251 Py_INCREF(Py_None);
1252 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001253}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001254#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001255
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001256#ifdef HAVE_LCHOWN
1257PyDoc_STRVAR(posix_lchown__doc__,
1258"lchown(path, uid, gid)\n\n\
1259Change the owner and group id of path to the numeric uid and gid.\n\
1260This function will not follow symbolic links.");
1261
1262static PyObject *
1263posix_lchown(PyObject *self, PyObject *args)
1264{
1265 char *path = NULL;
1266 int uid, gid;
1267 int res;
1268 if (!PyArg_ParseTuple(args, "etii:lchown",
1269 Py_FileSystemDefaultEncoding, &path,
1270 &uid, &gid))
1271 return NULL;
1272 Py_BEGIN_ALLOW_THREADS
1273 res = lchown(path, (uid_t) uid, (gid_t) gid);
1274 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001275 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001276 return posix_error_with_allocated_filename(path);
1277 PyMem_Free(path);
1278 Py_INCREF(Py_None);
1279 return Py_None;
1280}
1281#endif /* HAVE_LCHOWN */
1282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001283
Guido van Rossum36bc6801995-06-14 22:54:23 +00001284#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001285PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001286"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001287Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001288
Barry Warsaw53699e91996-12-10 23:23:01 +00001289static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001290posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001291{
1292 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001293 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001294
Barry Warsaw53699e91996-12-10 23:23:01 +00001295 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001296#if defined(PYOS_OS2) && defined(PYCC_GCC)
1297 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001298#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001299 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001300#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001301 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001302 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001304 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001306
Walter Dörwald3b918c32002-11-21 20:18:46 +00001307#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001308PyDoc_STRVAR(posix_getcwdu__doc__,
1309"getcwdu() -> path\n\n\
1310Return a unicode string representing the current working directory.");
1311
1312static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001313posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001314{
1315 char buf[1026];
1316 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001317
1318#ifdef Py_WIN_WIDE_FILENAMES
1319 if (unicode_file_names()) {
1320 wchar_t *wres;
1321 wchar_t wbuf[1026];
1322 Py_BEGIN_ALLOW_THREADS
1323 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1324 Py_END_ALLOW_THREADS
1325 if (wres == NULL)
1326 return posix_error();
1327 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1328 }
1329#endif
1330
1331 Py_BEGIN_ALLOW_THREADS
1332#if defined(PYOS_OS2) && defined(PYCC_GCC)
1333 res = _getcwd2(buf, sizeof buf);
1334#else
1335 res = getcwd(buf, sizeof buf);
1336#endif
1337 Py_END_ALLOW_THREADS
1338 if (res == NULL)
1339 return posix_error();
1340 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1341}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001342#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001343#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001345
Guido van Rossumb6775db1994-08-01 11:34:53 +00001346#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001347PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001348"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001349Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001350
Barry Warsaw53699e91996-12-10 23:23:01 +00001351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001352posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001353{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001354 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001355}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001356#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001358
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001359PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001360"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001361Return a list containing the names of the entries in the directory.\n\
1362\n\
1363 path: path of directory to list\n\
1364\n\
1365The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001366entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001367
Barry Warsaw53699e91996-12-10 23:23:01 +00001368static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001369posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001370{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001371 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001372 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001373#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001374
Barry Warsaw53699e91996-12-10 23:23:01 +00001375 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001376 HANDLE hFindFile;
1377 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001378 /* MAX_PATH characters could mean a bigger encoded string */
1379 char namebuf[MAX_PATH*2+5];
1380 char *bufptr = namebuf;
1381 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001382
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001383#ifdef Py_WIN_WIDE_FILENAMES
1384 /* If on wide-character-capable OS see if argument
1385 is Unicode and if so use wide API. */
1386 if (unicode_file_names()) {
1387 PyUnicodeObject *po;
1388 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1389 WIN32_FIND_DATAW wFileData;
1390 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1391 Py_UNICODE wch;
1392 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1393 wnamebuf[MAX_PATH] = L'\0';
1394 len = wcslen(wnamebuf);
1395 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1396 if (wch != L'/' && wch != L'\\' && wch != L':')
1397 wnamebuf[len++] = L'/';
1398 wcscpy(wnamebuf + len, L"*.*");
1399 if ((d = PyList_New(0)) == NULL)
1400 return NULL;
1401 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1402 if (hFindFile == INVALID_HANDLE_VALUE) {
1403 errno = GetLastError();
1404 if (errno == ERROR_FILE_NOT_FOUND) {
1405 return d;
1406 }
1407 Py_DECREF(d);
1408 return win32_error_unicode("FindFirstFileW", wnamebuf);
1409 }
1410 do {
1411 if (wFileData.cFileName[0] == L'.' &&
1412 (wFileData.cFileName[1] == L'\0' ||
1413 wFileData.cFileName[1] == L'.' &&
1414 wFileData.cFileName[2] == L'\0'))
1415 continue;
1416 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1417 if (v == NULL) {
1418 Py_DECREF(d);
1419 d = NULL;
1420 break;
1421 }
1422 if (PyList_Append(d, v) != 0) {
1423 Py_DECREF(v);
1424 Py_DECREF(d);
1425 d = NULL;
1426 break;
1427 }
1428 Py_DECREF(v);
1429 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1430
1431 if (FindClose(hFindFile) == FALSE) {
1432 Py_DECREF(d);
1433 return win32_error_unicode("FindClose", wnamebuf);
1434 }
1435 return d;
1436 }
1437 /* Drop the argument parsing error as narrow strings
1438 are also valid. */
1439 PyErr_Clear();
1440 }
1441#endif
1442
Tim Peters5aa91602002-01-30 05:46:57 +00001443 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001444 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001445 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001446 if (len > 0) {
1447 char ch = namebuf[len-1];
1448 if (ch != SEP && ch != ALTSEP && ch != ':')
1449 namebuf[len++] = '/';
1450 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001451 strcpy(namebuf + len, "*.*");
1452
Barry Warsaw53699e91996-12-10 23:23:01 +00001453 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001454 return NULL;
1455
1456 hFindFile = FindFirstFile(namebuf, &FileData);
1457 if (hFindFile == INVALID_HANDLE_VALUE) {
1458 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001459 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001460 return d;
1461 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001462 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001463 }
1464 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001465 if (FileData.cFileName[0] == '.' &&
1466 (FileData.cFileName[1] == '\0' ||
1467 FileData.cFileName[1] == '.' &&
1468 FileData.cFileName[2] == '\0'))
1469 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001470 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001471 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001472 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001473 d = NULL;
1474 break;
1475 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001476 if (PyList_Append(d, v) != 0) {
1477 Py_DECREF(v);
1478 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001479 d = NULL;
1480 break;
1481 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001482 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001483 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1484
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001485 if (FindClose(hFindFile) == FALSE) {
1486 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001487 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001488 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001489
1490 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001491
Tim Peters0bb44a42000-09-15 07:44:49 +00001492#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001493
1494#ifndef MAX_PATH
1495#define MAX_PATH CCHMAXPATH
1496#endif
1497 char *name, *pt;
1498 int len;
1499 PyObject *d, *v;
1500 char namebuf[MAX_PATH+5];
1501 HDIR hdir = 1;
1502 ULONG srchcnt = 1;
1503 FILEFINDBUF3 ep;
1504 APIRET rc;
1505
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001506 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001507 return NULL;
1508 if (len >= MAX_PATH) {
1509 PyErr_SetString(PyExc_ValueError, "path too long");
1510 return NULL;
1511 }
1512 strcpy(namebuf, name);
1513 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001514 if (*pt == ALTSEP)
1515 *pt = SEP;
1516 if (namebuf[len-1] != SEP)
1517 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001518 strcpy(namebuf + len, "*.*");
1519
1520 if ((d = PyList_New(0)) == NULL)
1521 return NULL;
1522
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001523 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1524 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001525 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001526 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1527 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1528 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001529
1530 if (rc != NO_ERROR) {
1531 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001532 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001533 }
1534
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001535 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001536 do {
1537 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001538 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001539 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001540
1541 strcpy(namebuf, ep.achName);
1542
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001543 /* Leave Case of Name Alone -- In Native Form */
1544 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001545
1546 v = PyString_FromString(namebuf);
1547 if (v == NULL) {
1548 Py_DECREF(d);
1549 d = NULL;
1550 break;
1551 }
1552 if (PyList_Append(d, v) != 0) {
1553 Py_DECREF(v);
1554 Py_DECREF(d);
1555 d = NULL;
1556 break;
1557 }
1558 Py_DECREF(v);
1559 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1560 }
1561
1562 return d;
1563#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001564
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001565 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001566 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001567 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001568 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001569 int arg_is_unicode = 1;
1570
1571 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1572 arg_is_unicode = 0;
1573 PyErr_Clear();
1574 }
1575 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001576 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001577 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001578 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001579 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001580 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001581 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001582 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001583 return NULL;
1584 }
1585 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001586 if (ep->d_name[0] == '.' &&
1587 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001588 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001589 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001590 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001591 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001592 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001593 d = NULL;
1594 break;
1595 }
Just van Rossum46c97842003-02-25 21:42:15 +00001596#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001597 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001598 PyObject *w;
1599
1600 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001601 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001602 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001603 if (w != NULL) {
1604 Py_DECREF(v);
1605 v = w;
1606 }
1607 else {
1608 /* fall back to the original byte string, as
1609 discussed in patch #683592 */
1610 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001611 }
Just van Rossum46c97842003-02-25 21:42:15 +00001612 }
1613#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001614 if (PyList_Append(d, v) != 0) {
1615 Py_DECREF(v);
1616 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001617 d = NULL;
1618 break;
1619 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001620 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001621 }
1622 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001623 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001624
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001625 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001626
Tim Peters0bb44a42000-09-15 07:44:49 +00001627#endif /* which OS */
1628} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001629
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001630#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001631/* A helper function for abspath on win32 */
1632static PyObject *
1633posix__getfullpathname(PyObject *self, PyObject *args)
1634{
1635 /* assume encoded strings wont more than double no of chars */
1636 char inbuf[MAX_PATH*2];
1637 char *inbufp = inbuf;
1638 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1639 char outbuf[MAX_PATH*2];
1640 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001641#ifdef Py_WIN_WIDE_FILENAMES
1642 if (unicode_file_names()) {
1643 PyUnicodeObject *po;
1644 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1645 Py_UNICODE woutbuf[MAX_PATH*2];
1646 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001647 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001648 sizeof(woutbuf)/sizeof(woutbuf[0]),
1649 woutbuf, &wtemp))
1650 return win32_error("GetFullPathName", "");
1651 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1652 }
1653 /* Drop the argument parsing error as narrow strings
1654 are also valid. */
1655 PyErr_Clear();
1656 }
1657#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001658 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1659 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001660 &insize))
1661 return NULL;
1662 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1663 outbuf, &temp))
1664 return win32_error("GetFullPathName", inbuf);
1665 return PyString_FromString(outbuf);
1666} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001667#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001669PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001670"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001671Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001672
Barry Warsaw53699e91996-12-10 23:23:01 +00001673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001674posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001675{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001676 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001677 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001678 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001679
1680#ifdef Py_WIN_WIDE_FILENAMES
1681 if (unicode_file_names()) {
1682 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001683 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001684 Py_BEGIN_ALLOW_THREADS
1685 /* PyUnicode_AS_UNICODE OK without thread lock as
1686 it is a simple dereference. */
1687 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1688 Py_END_ALLOW_THREADS
1689 if (res < 0)
1690 return posix_error();
1691 Py_INCREF(Py_None);
1692 return Py_None;
1693 }
1694 /* Drop the argument parsing error as narrow strings
1695 are also valid. */
1696 PyErr_Clear();
1697 }
1698#endif
1699
Tim Peters5aa91602002-01-30 05:46:57 +00001700 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001701 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001702 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001703 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001704#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001705 res = mkdir(path);
1706#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001707 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001708#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001709 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001710 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001711 return posix_error_with_allocated_filename(path);
1712 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001713 Py_INCREF(Py_None);
1714 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001715}
1716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001717
Guido van Rossumb6775db1994-08-01 11:34:53 +00001718#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001719#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1720#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1721#include <sys/resource.h>
1722#endif
1723#endif
1724
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001725PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001726"nice(inc) -> new_priority\n\n\
1727Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001728
Barry Warsaw53699e91996-12-10 23:23:01 +00001729static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001730posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001731{
1732 int increment, value;
1733
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001734 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001735 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001736
1737 /* There are two flavours of 'nice': one that returns the new
1738 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001739 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1740 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001741
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001742 If we are of the nice family that returns the new priority, we
1743 need to clear errno before the call, and check if errno is filled
1744 before calling posix_error() on a returnvalue of -1, because the
1745 -1 may be the actual new priority! */
1746
1747 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001748 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001749#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001750 if (value == 0)
1751 value = getpriority(PRIO_PROCESS, 0);
1752#endif
1753 if (value == -1 && errno != 0)
1754 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001755 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001756 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001757}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001758#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001760
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001761PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001762"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001763Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001764
Barry Warsaw53699e91996-12-10 23:23:01 +00001765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001766posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001767{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001768#ifdef MS_WINDOWS
1769 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1770#else
1771 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1772#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001773}
1774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001775
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001776PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001777"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001778Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001779
Barry Warsaw53699e91996-12-10 23:23:01 +00001780static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001781posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001782{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001783#ifdef MS_WINDOWS
1784 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1785#else
1786 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1787#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001788}
1789
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001790
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001791PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001792"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001793Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001794
Barry Warsaw53699e91996-12-10 23:23:01 +00001795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001796posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001797{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001798#ifdef MS_WINDOWS
1799 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1800#else
1801 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1802#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001803}
1804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001805
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001806#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001807PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001808"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001809Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001810
Barry Warsaw53699e91996-12-10 23:23:01 +00001811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001812posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001813{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001814 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001815 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001816 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001817 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001818 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001819 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001820 Py_END_ALLOW_THREADS
1821 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001822}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001823#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001824
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001825
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001826PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001827"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001828Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001829
Barry Warsaw53699e91996-12-10 23:23:01 +00001830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001831posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001832{
1833 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001834 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001835 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001836 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001837 if (i < 0)
1838 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001839 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001840}
1841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001842
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001843PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001844"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001845Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001846
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001847PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001848"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001849Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001850
Barry Warsaw53699e91996-12-10 23:23:01 +00001851static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001852posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001853{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001854#ifdef MS_WINDOWS
1855 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1856#else
1857 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1858#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001859}
1860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001861
Guido van Rossumb6775db1994-08-01 11:34:53 +00001862#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001863PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001864"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001865Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001866
Barry Warsaw53699e91996-12-10 23:23:01 +00001867static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001868posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001869{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001870 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001871 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001872
Barry Warsaw53699e91996-12-10 23:23:01 +00001873 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001874 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001875 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001876 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001877 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001878 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001879 u.sysname,
1880 u.nodename,
1881 u.release,
1882 u.version,
1883 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001884}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001885#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001886
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001887static int
1888extract_time(PyObject *t, long* sec, long* usec)
1889{
1890 long intval;
1891 if (PyFloat_Check(t)) {
1892 double tval = PyFloat_AsDouble(t);
1893 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1894 if (!intobj)
1895 return -1;
1896 intval = PyInt_AsLong(intobj);
1897 Py_DECREF(intobj);
1898 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001899 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001900 if (*usec < 0)
1901 /* If rounding gave us a negative number,
1902 truncate. */
1903 *usec = 0;
1904 return 0;
1905 }
1906 intval = PyInt_AsLong(t);
1907 if (intval == -1 && PyErr_Occurred())
1908 return -1;
1909 *sec = intval;
1910 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001911 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001912}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001913
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001914PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001915"utime(path, (atime, utime))\n\
1916utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001917Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001918second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001919
Barry Warsaw53699e91996-12-10 23:23:01 +00001920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001921posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001922{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001923 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001924 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001925 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001926 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001927
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001928#if defined(HAVE_UTIMES)
1929 struct timeval buf[2];
1930#define ATIME buf[0].tv_sec
1931#define MTIME buf[1].tv_sec
1932#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001933/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001934 struct utimbuf buf;
1935#define ATIME buf.actime
1936#define MTIME buf.modtime
1937#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001938#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001939 time_t buf[2];
1940#define ATIME buf[0]
1941#define MTIME buf[1]
1942#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001943#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001944
Mark Hammond817c9292003-12-03 01:22:38 +00001945 int have_unicode_filename = 0;
1946#ifdef Py_WIN_WIDE_FILENAMES
1947 PyUnicodeObject *obwpath;
1948 wchar_t *wpath;
1949 if (unicode_file_names()) {
1950 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
1951 wpath = PyUnicode_AS_UNICODE(obwpath);
1952 have_unicode_filename = 1;
1953 } else
1954 /* Drop the argument parsing error as narrow strings
1955 are also valid. */
1956 PyErr_Clear();
1957 }
1958#endif /* Py_WIN_WIDE_FILENAMES */
1959
1960 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00001961 !PyArg_ParseTuple(args, "etO:utime",
1962 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001963 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001964 if (arg == Py_None) {
1965 /* optional time values not given */
1966 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00001967#ifdef Py_WIN_WIDE_FILENAMES
1968 if (have_unicode_filename)
1969 res = _wutime(wpath, NULL);
1970 else
1971#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00001972 res = utime(path, NULL);
1973 Py_END_ALLOW_THREADS
1974 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001975 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001976 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001977 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001978 return NULL;
1979 }
1980 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001981 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1982 &atime, &ausec) == -1)
1983 return NULL;
1984 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1985 &mtime, &musec) == -1)
1986 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001987 ATIME = atime;
1988 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001989#ifdef HAVE_UTIMES
1990 buf[0].tv_usec = ausec;
1991 buf[1].tv_usec = musec;
1992 Py_BEGIN_ALLOW_THREADS
1993 res = utimes(path, buf);
1994 Py_END_ALLOW_THREADS
1995#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00001996 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00001997#ifdef Py_WIN_WIDE_FILENAMES
1998 if (have_unicode_filename)
1999 /* utime is OK with utimbuf, but _wutime insists
2000 on _utimbuf (the msvc headers assert the
2001 underscore version is ansi) */
2002 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2003 else
2004#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002005 res = utime(path, UTIME_ARG);
2006 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002007#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002008 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00002009 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002010 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002011 Py_INCREF(Py_None);
2012 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002013#undef UTIME_ARG
2014#undef ATIME
2015#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002016}
2017
Guido van Rossum85e3b011991-06-03 12:42:10 +00002018
Guido van Rossum3b066191991-06-04 19:40:25 +00002019/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002020
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002021PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002022"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002023Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002024
Barry Warsaw53699e91996-12-10 23:23:01 +00002025static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002026posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002027{
2028 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002029 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002030 return NULL;
2031 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002032 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002033}
2034
Martin v. Löwis114619e2002-10-07 06:44:21 +00002035#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2036static void
2037free_string_array(char **array, int count)
2038{
2039 int i;
2040 for (i = 0; i < count; i++)
2041 PyMem_Free(array[i]);
2042 PyMem_DEL(array);
2043}
2044#endif
2045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002046
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002047#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002048PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002049"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002050Execute an executable path with arguments, replacing current process.\n\
2051\n\
2052 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002053 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002054
Barry Warsaw53699e91996-12-10 23:23:01 +00002055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002056posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002057{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002058 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002059 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002060 char **argvlist;
2061 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002062 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002063
Guido van Rossum89b33251993-10-22 14:26:06 +00002064 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002065 argv is a list or tuple of strings. */
2066
Martin v. Löwis114619e2002-10-07 06:44:21 +00002067 if (!PyArg_ParseTuple(args, "etO:execv",
2068 Py_FileSystemDefaultEncoding,
2069 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002070 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002071 if (PyList_Check(argv)) {
2072 argc = PyList_Size(argv);
2073 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002074 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002075 else if (PyTuple_Check(argv)) {
2076 argc = PyTuple_Size(argv);
2077 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002078 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002079 else {
Fred Drake661ea262000-10-24 19:57:45 +00002080 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002081 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002082 return NULL;
2083 }
2084
2085 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002086 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002087 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002088 return NULL;
2089 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002090
Barry Warsaw53699e91996-12-10 23:23:01 +00002091 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002092 if (argvlist == NULL) {
2093 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002094 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002095 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002096 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002097 if (!PyArg_Parse((*getitem)(argv, i), "et",
2098 Py_FileSystemDefaultEncoding,
2099 &argvlist[i])) {
2100 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002101 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002102 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002103 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002104 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002105
Guido van Rossum85e3b011991-06-03 12:42:10 +00002106 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002107 }
2108 argvlist[argc] = NULL;
2109
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002110 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002111
Guido van Rossum85e3b011991-06-03 12:42:10 +00002112 /* If we get here it's definitely an error */
2113
Martin v. Löwis114619e2002-10-07 06:44:21 +00002114 free_string_array(argvlist, argc);
2115 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002116 return posix_error();
2117}
2118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002120PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002121"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002122Execute a path with arguments and environment, replacing current process.\n\
2123\n\
2124 path: path of executable file\n\
2125 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002126 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002127
Barry Warsaw53699e91996-12-10 23:23:01 +00002128static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002129posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002130{
2131 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002132 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002133 char **argvlist;
2134 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002135 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002136 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002137 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002138 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002139
2140 /* execve has three arguments: (path, argv, env), where
2141 argv is a list or tuple of strings and env is a dictionary
2142 like posix.environ. */
2143
Martin v. Löwis114619e2002-10-07 06:44:21 +00002144 if (!PyArg_ParseTuple(args, "etOO:execve",
2145 Py_FileSystemDefaultEncoding,
2146 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002147 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002148 if (PyList_Check(argv)) {
2149 argc = PyList_Size(argv);
2150 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002151 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002152 else if (PyTuple_Check(argv)) {
2153 argc = PyTuple_Size(argv);
2154 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002155 }
2156 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002157 PyErr_SetString(PyExc_TypeError,
2158 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002159 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002160 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002161 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002162 PyErr_SetString(PyExc_TypeError,
2163 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002164 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002165 }
2166
Guido van Rossum50422b42000-04-26 20:34:28 +00002167 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002168 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002169 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002170 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002171 }
2172
Barry Warsaw53699e91996-12-10 23:23:01 +00002173 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002174 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002175 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002176 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002177 }
2178 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002179 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002180 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002181 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002182 &argvlist[i]))
2183 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002184 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002185 goto fail_1;
2186 }
2187 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002188 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002189 argvlist[argc] = NULL;
2190
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002191 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002192 if (i < 0)
2193 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002194 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002195 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002196 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002197 goto fail_1;
2198 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002199 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002200 keys = PyMapping_Keys(env);
2201 vals = PyMapping_Values(env);
2202 if (!keys || !vals)
2203 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002204 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2205 PyErr_SetString(PyExc_TypeError,
2206 "execve(): env.keys() or env.values() is not a list");
2207 goto fail_2;
2208 }
Tim Peters5aa91602002-01-30 05:46:57 +00002209
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002210 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002211 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002212 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002213
2214 key = PyList_GetItem(keys, pos);
2215 val = PyList_GetItem(vals, pos);
2216 if (!key || !val)
2217 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002218
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002219 if (!PyArg_Parse(
2220 key,
2221 "s;execve() arg 3 contains a non-string key",
2222 &k) ||
2223 !PyArg_Parse(
2224 val,
2225 "s;execve() arg 3 contains a non-string value",
2226 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002227 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002228 goto fail_2;
2229 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002230
2231#if defined(PYOS_OS2)
2232 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2233 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2234#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002235 len = PyString_Size(key) + PyString_Size(val) + 2;
2236 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002237 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002238 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002239 goto fail_2;
2240 }
Tim Petersc8996f52001-12-03 20:41:00 +00002241 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002242 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002243#if defined(PYOS_OS2)
2244 }
2245#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002246 }
2247 envlist[envc] = 0;
2248
2249 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002250
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002251 /* If we get here it's definitely an error */
2252
2253 (void) posix_error();
2254
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002255 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002256 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002257 PyMem_DEL(envlist[envc]);
2258 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002259 fail_1:
2260 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002261 Py_XDECREF(vals);
2262 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002263 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002264 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002265 return NULL;
2266}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002267#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002268
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002269
Guido van Rossuma1065681999-01-25 23:20:23 +00002270#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002271PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002272"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002273Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002274\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002275 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002276 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002277 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002278
2279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002280posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002281{
2282 char *path;
2283 PyObject *argv;
2284 char **argvlist;
2285 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002286 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002287 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002288
2289 /* spawnv has three arguments: (mode, path, argv), where
2290 argv is a list or tuple of strings. */
2291
Martin v. Löwis114619e2002-10-07 06:44:21 +00002292 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2293 Py_FileSystemDefaultEncoding,
2294 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002295 return NULL;
2296 if (PyList_Check(argv)) {
2297 argc = PyList_Size(argv);
2298 getitem = PyList_GetItem;
2299 }
2300 else if (PyTuple_Check(argv)) {
2301 argc = PyTuple_Size(argv);
2302 getitem = PyTuple_GetItem;
2303 }
2304 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002305 PyErr_SetString(PyExc_TypeError,
2306 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002307 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002308 return NULL;
2309 }
2310
2311 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002312 if (argvlist == NULL) {
2313 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002314 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002315 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002316 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002317 if (!PyArg_Parse((*getitem)(argv, i), "et",
2318 Py_FileSystemDefaultEncoding,
2319 &argvlist[i])) {
2320 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002321 PyErr_SetString(
2322 PyExc_TypeError,
2323 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002324 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002325 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002326 }
2327 }
2328 argvlist[argc] = NULL;
2329
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002330#if defined(PYOS_OS2) && defined(PYCC_GCC)
2331 Py_BEGIN_ALLOW_THREADS
2332 spawnval = spawnv(mode, path, argvlist);
2333 Py_END_ALLOW_THREADS
2334#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002335 if (mode == _OLD_P_OVERLAY)
2336 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002337
Tim Peters25059d32001-12-07 20:35:43 +00002338 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002339 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002340 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002341#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002342
Martin v. Löwis114619e2002-10-07 06:44:21 +00002343 free_string_array(argvlist, argc);
2344 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002345
Fred Drake699f3522000-06-29 21:12:41 +00002346 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002347 return posix_error();
2348 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002349#if SIZEOF_LONG == SIZEOF_VOID_P
2350 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002351#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002352 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002353#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002354}
2355
2356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002357PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002358"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002359Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002360\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002361 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002362 path: path of executable file\n\
2363 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002364 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002365
2366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002367posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002368{
2369 char *path;
2370 PyObject *argv, *env;
2371 char **argvlist;
2372 char **envlist;
2373 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2374 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002375 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002376 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002377 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002378
2379 /* spawnve has four arguments: (mode, path, argv, env), where
2380 argv is a list or tuple of strings and env is a dictionary
2381 like posix.environ. */
2382
Martin v. Löwis114619e2002-10-07 06:44:21 +00002383 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2384 Py_FileSystemDefaultEncoding,
2385 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002386 return NULL;
2387 if (PyList_Check(argv)) {
2388 argc = PyList_Size(argv);
2389 getitem = PyList_GetItem;
2390 }
2391 else if (PyTuple_Check(argv)) {
2392 argc = PyTuple_Size(argv);
2393 getitem = PyTuple_GetItem;
2394 }
2395 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002396 PyErr_SetString(PyExc_TypeError,
2397 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002398 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002399 }
2400 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002401 PyErr_SetString(PyExc_TypeError,
2402 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002403 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002404 }
2405
2406 argvlist = PyMem_NEW(char *, argc+1);
2407 if (argvlist == NULL) {
2408 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002409 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002410 }
2411 for (i = 0; i < argc; i++) {
2412 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002413 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002414 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002415 &argvlist[i]))
2416 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002417 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002418 goto fail_1;
2419 }
2420 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002421 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002422 argvlist[argc] = NULL;
2423
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002424 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002425 if (i < 0)
2426 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002427 envlist = PyMem_NEW(char *, i + 1);
2428 if (envlist == NULL) {
2429 PyErr_NoMemory();
2430 goto fail_1;
2431 }
2432 envc = 0;
2433 keys = PyMapping_Keys(env);
2434 vals = PyMapping_Values(env);
2435 if (!keys || !vals)
2436 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002437 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2438 PyErr_SetString(PyExc_TypeError,
2439 "spawnve(): env.keys() or env.values() is not a list");
2440 goto fail_2;
2441 }
Tim Peters5aa91602002-01-30 05:46:57 +00002442
Guido van Rossuma1065681999-01-25 23:20:23 +00002443 for (pos = 0; pos < i; pos++) {
2444 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002445 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002446
2447 key = PyList_GetItem(keys, pos);
2448 val = PyList_GetItem(vals, pos);
2449 if (!key || !val)
2450 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002451
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002452 if (!PyArg_Parse(
2453 key,
2454 "s;spawnve() arg 3 contains a non-string key",
2455 &k) ||
2456 !PyArg_Parse(
2457 val,
2458 "s;spawnve() arg 3 contains a non-string value",
2459 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002460 {
2461 goto fail_2;
2462 }
Tim Petersc8996f52001-12-03 20:41:00 +00002463 len = PyString_Size(key) + PyString_Size(val) + 2;
2464 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002465 if (p == NULL) {
2466 PyErr_NoMemory();
2467 goto fail_2;
2468 }
Tim Petersc8996f52001-12-03 20:41:00 +00002469 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002470 envlist[envc++] = p;
2471 }
2472 envlist[envc] = 0;
2473
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002474#if defined(PYOS_OS2) && defined(PYCC_GCC)
2475 Py_BEGIN_ALLOW_THREADS
2476 spawnval = spawnve(mode, path, argvlist, envlist);
2477 Py_END_ALLOW_THREADS
2478#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002479 if (mode == _OLD_P_OVERLAY)
2480 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002481
2482 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002483 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002484 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002485#endif
Tim Peters25059d32001-12-07 20:35:43 +00002486
Fred Drake699f3522000-06-29 21:12:41 +00002487 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002488 (void) posix_error();
2489 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002490#if SIZEOF_LONG == SIZEOF_VOID_P
2491 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002492#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002493 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002494#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002495
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002496 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002497 while (--envc >= 0)
2498 PyMem_DEL(envlist[envc]);
2499 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002500 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002501 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002502 Py_XDECREF(vals);
2503 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002504 fail_0:
2505 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002506 return res;
2507}
2508#endif /* HAVE_SPAWNV */
2509
2510
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002511#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002512PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002513"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002514Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2515\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002516Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002517
2518static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002519posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002520{
Neal Norwitze241ce82003-02-17 18:17:05 +00002521 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002522 if (pid == -1)
2523 return posix_error();
2524 PyOS_AfterFork();
2525 return PyInt_FromLong((long)pid);
2526}
2527#endif
2528
2529
Guido van Rossumad0ee831995-03-01 10:34:45 +00002530#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002531PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002532"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002533Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002534Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002535
Barry Warsaw53699e91996-12-10 23:23:01 +00002536static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002537posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002538{
Neal Norwitze241ce82003-02-17 18:17:05 +00002539 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002540 if (pid == -1)
2541 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002542 if (pid == 0)
2543 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002544 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002545}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002546#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002547
Neal Norwitzb59798b2003-03-21 01:43:31 +00002548/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00002549/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2550#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00002551#define DEV_PTY_FILE "/dev/ptc"
2552#define HAVE_DEV_PTMX
2553#else
2554#define DEV_PTY_FILE "/dev/ptmx"
2555#endif
2556
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002557#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002558#ifdef HAVE_PTY_H
2559#include <pty.h>
2560#else
2561#ifdef HAVE_LIBUTIL_H
2562#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002563#endif /* HAVE_LIBUTIL_H */
2564#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002565#ifdef HAVE_STROPTS_H
2566#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002567#endif
2568#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002569
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002570#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002571PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002572"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002573Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002574
2575static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002576posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002577{
2578 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002579#ifndef HAVE_OPENPTY
2580 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002581#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002582#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002583 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002584#ifdef sun
2585 extern char *ptsname();
2586#endif
2587#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002588
Thomas Wouters70c21a12000-07-14 14:28:33 +00002589#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002590 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2591 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002592#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00002593 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2594 if (slave_name == NULL)
2595 return posix_error();
2596
2597 slave_fd = open(slave_name, O_RDWR);
2598 if (slave_fd < 0)
2599 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002600#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00002601 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002602 if (master_fd < 0)
2603 return posix_error();
2604 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002605 /* change permission of slave */
2606 if (grantpt(master_fd) < 0) {
2607 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002608 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002609 }
2610 /* unlock slave */
2611 if (unlockpt(master_fd) < 0) {
2612 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002613 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002614 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002615 signal(SIGCHLD, sig_saved);
2616 slave_name = ptsname(master_fd); /* get name of slave */
2617 if (slave_name == NULL)
2618 return posix_error();
2619 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2620 if (slave_fd < 0)
2621 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002622#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002623 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2624 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002625#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002626 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002627#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002628#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002629#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002630
Fred Drake8cef4cf2000-06-28 16:40:38 +00002631 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002632
Fred Drake8cef4cf2000-06-28 16:40:38 +00002633}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002634#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002635
2636#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002637PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002638"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002639Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2640Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002641To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002642
2643static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002644posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002645{
2646 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002647
Fred Drake8cef4cf2000-06-28 16:40:38 +00002648 pid = forkpty(&master_fd, NULL, NULL, NULL);
2649 if (pid == -1)
2650 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002651 if (pid == 0)
2652 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002653 return Py_BuildValue("(ii)", pid, master_fd);
2654}
2655#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002656
Guido van Rossumad0ee831995-03-01 10:34:45 +00002657#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002658PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002659"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002660Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002661
Barry Warsaw53699e91996-12-10 23:23:01 +00002662static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002663posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002664{
Barry Warsaw53699e91996-12-10 23:23:01 +00002665 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002666}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002667#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002668
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002669
Guido van Rossumad0ee831995-03-01 10:34:45 +00002670#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002671PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002672"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002673Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002674
Barry Warsaw53699e91996-12-10 23:23:01 +00002675static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002676posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002677{
Barry Warsaw53699e91996-12-10 23:23:01 +00002678 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002679}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002680#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002681
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002682
Guido van Rossumad0ee831995-03-01 10:34:45 +00002683#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002684PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002685"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002686Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002687
Barry Warsaw53699e91996-12-10 23:23:01 +00002688static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002689posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002690{
Barry Warsaw53699e91996-12-10 23:23:01 +00002691 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002692}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002693#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002694
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002695
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002696PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002697"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002698Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002699
Barry Warsaw53699e91996-12-10 23:23:01 +00002700static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002701posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002702{
Barry Warsaw53699e91996-12-10 23:23:01 +00002703 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002704}
2705
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002706
Fred Drakec9680921999-12-13 16:37:25 +00002707#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002708PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002709"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002710Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002711
2712static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002713posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00002714{
2715 PyObject *result = NULL;
2716
Fred Drakec9680921999-12-13 16:37:25 +00002717#ifdef NGROUPS_MAX
2718#define MAX_GROUPS NGROUPS_MAX
2719#else
2720 /* defined to be 16 on Solaris7, so this should be a small number */
2721#define MAX_GROUPS 64
2722#endif
2723 gid_t grouplist[MAX_GROUPS];
2724 int n;
2725
2726 n = getgroups(MAX_GROUPS, grouplist);
2727 if (n < 0)
2728 posix_error();
2729 else {
2730 result = PyList_New(n);
2731 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00002732 int i;
2733 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00002734 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00002735 if (o == NULL) {
2736 Py_DECREF(result);
2737 result = NULL;
2738 break;
2739 }
2740 PyList_SET_ITEM(result, i, o);
2741 }
2742 }
2743 }
Neal Norwitze241ce82003-02-17 18:17:05 +00002744
Fred Drakec9680921999-12-13 16:37:25 +00002745 return result;
2746}
2747#endif
2748
Martin v. Löwis606edc12002-06-13 21:09:11 +00002749#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002750PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002751"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002752Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002753
2754static PyObject *
2755posix_getpgid(PyObject *self, PyObject *args)
2756{
2757 int pid, pgid;
2758 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2759 return NULL;
2760 pgid = getpgid(pid);
2761 if (pgid < 0)
2762 return posix_error();
2763 return PyInt_FromLong((long)pgid);
2764}
2765#endif /* HAVE_GETPGID */
2766
2767
Guido van Rossumb6775db1994-08-01 11:34:53 +00002768#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002769PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002770"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002771Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002772
Barry Warsaw53699e91996-12-10 23:23:01 +00002773static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002774posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00002775{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002776#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002777 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002778#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002779 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002780#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002781}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002782#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002784
Guido van Rossumb6775db1994-08-01 11:34:53 +00002785#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002786PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002787"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002788Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002789
Barry Warsaw53699e91996-12-10 23:23:01 +00002790static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002791posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002792{
Guido van Rossum64933891994-10-20 21:56:42 +00002793#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002794 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002795#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002796 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002797#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002798 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002799 Py_INCREF(Py_None);
2800 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002801}
2802
Guido van Rossumb6775db1994-08-01 11:34:53 +00002803#endif /* HAVE_SETPGRP */
2804
Guido van Rossumad0ee831995-03-01 10:34:45 +00002805#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002806PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002807"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002808Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002809
Barry Warsaw53699e91996-12-10 23:23:01 +00002810static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002811posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002812{
Barry Warsaw53699e91996-12-10 23:23:01 +00002813 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002814}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002815#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002816
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002817
Fred Drake12c6e2d1999-12-14 21:25:03 +00002818#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002819PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002820"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002821Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002822
2823static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002824posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002825{
Neal Norwitze241ce82003-02-17 18:17:05 +00002826 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00002827 char *name;
2828 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002829
Fred Drakea30680b2000-12-06 21:24:28 +00002830 errno = 0;
2831 name = getlogin();
2832 if (name == NULL) {
2833 if (errno)
2834 posix_error();
2835 else
2836 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002837 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002838 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002839 else
2840 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002841 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00002842
Fred Drake12c6e2d1999-12-14 21:25:03 +00002843 return result;
2844}
2845#endif
2846
Guido van Rossumad0ee831995-03-01 10:34:45 +00002847#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002848PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002849"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002850Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002851
Barry Warsaw53699e91996-12-10 23:23:01 +00002852static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002853posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002854{
Barry Warsaw53699e91996-12-10 23:23:01 +00002855 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002856}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002857#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002858
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002859
Guido van Rossumad0ee831995-03-01 10:34:45 +00002860#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002861PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002862"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002863Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002864
Barry Warsaw53699e91996-12-10 23:23:01 +00002865static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002866posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002867{
2868 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002869 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002870 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002871#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002872 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2873 APIRET rc;
2874 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002875 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002876
2877 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2878 APIRET rc;
2879 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002880 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002881
2882 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002883 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002884#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002885 if (kill(pid, sig) == -1)
2886 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002887#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002888 Py_INCREF(Py_None);
2889 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002890}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002891#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002892
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002893#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002894PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002895"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002896Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002897
2898static PyObject *
2899posix_killpg(PyObject *self, PyObject *args)
2900{
2901 int pgid, sig;
2902 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2903 return NULL;
2904 if (killpg(pgid, sig) == -1)
2905 return posix_error();
2906 Py_INCREF(Py_None);
2907 return Py_None;
2908}
2909#endif
2910
Guido van Rossumc0125471996-06-28 18:55:32 +00002911#ifdef HAVE_PLOCK
2912
2913#ifdef HAVE_SYS_LOCK_H
2914#include <sys/lock.h>
2915#endif
2916
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002917PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002918"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002919Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002920
Barry Warsaw53699e91996-12-10 23:23:01 +00002921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002922posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002923{
2924 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002925 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002926 return NULL;
2927 if (plock(op) == -1)
2928 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002929 Py_INCREF(Py_None);
2930 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002931}
2932#endif
2933
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002934
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002935#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002936PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002937"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002938Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002939
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002940#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002941#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002942static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002943async_system(const char *command)
2944{
2945 char *p, errormsg[256], args[1024];
2946 RESULTCODES rcodes;
2947 APIRET rc;
2948 char *shell = getenv("COMSPEC");
2949 if (!shell)
2950 shell = "cmd";
2951
2952 strcpy(args, shell);
2953 p = &args[ strlen(args)+1 ];
2954 strcpy(p, "/c ");
2955 strcat(p, command);
2956 p += strlen(p) + 1;
2957 *p = '\0';
2958
2959 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002960 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002961 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002962 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002963 &rcodes, shell);
2964 return rc;
2965}
2966
Guido van Rossumd48f2521997-12-05 22:19:34 +00002967static FILE *
2968popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002969{
2970 HFILE rhan, whan;
2971 FILE *retfd = NULL;
2972 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2973
Guido van Rossumd48f2521997-12-05 22:19:34 +00002974 if (rc != NO_ERROR) {
2975 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002976 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002977 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002978
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002979 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2980 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002981
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002982 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2983 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002984
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002985 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2986 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002987
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002988 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002989 }
2990
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002991 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2992 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002993
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002994 if (rc == NO_ERROR)
2995 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2996
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002997 close(oldfd); /* And Close Saved STDOUT Handle */
2998 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002999
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003000 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3001 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003002
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003003 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3004 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003005
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003006 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3007 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003008
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003009 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003010 }
3011
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003012 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3013 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003014
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003015 if (rc == NO_ERROR)
3016 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3017
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003018 close(oldfd); /* And Close Saved STDIN Handle */
3019 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003020
Guido van Rossumd48f2521997-12-05 22:19:34 +00003021 } else {
3022 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003023 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003024 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003025}
3026
3027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003028posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003029{
3030 char *name;
3031 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003032 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003033 FILE *fp;
3034 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003035 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003036 return NULL;
3037 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003038 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003039 Py_END_ALLOW_THREADS
3040 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003041 return os2_error(err);
3042
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003043 f = PyFile_FromFile(fp, name, mode, fclose);
3044 if (f != NULL)
3045 PyFile_SetBufSize(f, bufsize);
3046 return f;
3047}
3048
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003049#elif defined(PYCC_GCC)
3050
3051/* standard posix version of popen() support */
3052static PyObject *
3053posix_popen(PyObject *self, PyObject *args)
3054{
3055 char *name;
3056 char *mode = "r";
3057 int bufsize = -1;
3058 FILE *fp;
3059 PyObject *f;
3060 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3061 return NULL;
3062 Py_BEGIN_ALLOW_THREADS
3063 fp = popen(name, mode);
3064 Py_END_ALLOW_THREADS
3065 if (fp == NULL)
3066 return posix_error();
3067 f = PyFile_FromFile(fp, name, mode, pclose);
3068 if (f != NULL)
3069 PyFile_SetBufSize(f, bufsize);
3070 return f;
3071}
3072
3073/* fork() under OS/2 has lots'o'warts
3074 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3075 * most of this code is a ripoff of the win32 code, but using the
3076 * capabilities of EMX's C library routines
3077 */
3078
3079/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3080#define POPEN_1 1
3081#define POPEN_2 2
3082#define POPEN_3 3
3083#define POPEN_4 4
3084
3085static PyObject *_PyPopen(char *, int, int, int);
3086static int _PyPclose(FILE *file);
3087
3088/*
3089 * Internal dictionary mapping popen* file pointers to process handles,
3090 * for use when retrieving the process exit code. See _PyPclose() below
3091 * for more information on this dictionary's use.
3092 */
3093static PyObject *_PyPopenProcs = NULL;
3094
3095/* os2emx version of popen2()
3096 *
3097 * The result of this function is a pipe (file) connected to the
3098 * process's stdin, and a pipe connected to the process's stdout.
3099 */
3100
3101static PyObject *
3102os2emx_popen2(PyObject *self, PyObject *args)
3103{
3104 PyObject *f;
3105 int tm=0;
3106
3107 char *cmdstring;
3108 char *mode = "t";
3109 int bufsize = -1;
3110 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3111 return NULL;
3112
3113 if (*mode == 't')
3114 tm = O_TEXT;
3115 else if (*mode != 'b') {
3116 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3117 return NULL;
3118 } else
3119 tm = O_BINARY;
3120
3121 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3122
3123 return f;
3124}
3125
3126/*
3127 * Variation on os2emx.popen2
3128 *
3129 * The result of this function is 3 pipes - the process's stdin,
3130 * stdout and stderr
3131 */
3132
3133static PyObject *
3134os2emx_popen3(PyObject *self, PyObject *args)
3135{
3136 PyObject *f;
3137 int tm = 0;
3138
3139 char *cmdstring;
3140 char *mode = "t";
3141 int bufsize = -1;
3142 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3143 return NULL;
3144
3145 if (*mode == 't')
3146 tm = O_TEXT;
3147 else if (*mode != 'b') {
3148 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3149 return NULL;
3150 } else
3151 tm = O_BINARY;
3152
3153 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3154
3155 return f;
3156}
3157
3158/*
3159 * Variation on os2emx.popen2
3160 *
Tim Peters11b23062003-04-23 02:39:17 +00003161 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003162 * and stdout+stderr combined as a single pipe.
3163 */
3164
3165static PyObject *
3166os2emx_popen4(PyObject *self, PyObject *args)
3167{
3168 PyObject *f;
3169 int tm = 0;
3170
3171 char *cmdstring;
3172 char *mode = "t";
3173 int bufsize = -1;
3174 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3175 return NULL;
3176
3177 if (*mode == 't')
3178 tm = O_TEXT;
3179 else if (*mode != 'b') {
3180 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3181 return NULL;
3182 } else
3183 tm = O_BINARY;
3184
3185 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3186
3187 return f;
3188}
3189
3190/* a couple of structures for convenient handling of multiple
3191 * file handles and pipes
3192 */
3193struct file_ref
3194{
3195 int handle;
3196 int flags;
3197};
3198
3199struct pipe_ref
3200{
3201 int rd;
3202 int wr;
3203};
3204
3205/* The following code is derived from the win32 code */
3206
3207static PyObject *
3208_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3209{
3210 struct file_ref stdio[3];
3211 struct pipe_ref p_fd[3];
3212 FILE *p_s[3];
3213 int file_count, i, pipe_err, pipe_pid;
3214 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3215 PyObject *f, *p_f[3];
3216
3217 /* file modes for subsequent fdopen's on pipe handles */
3218 if (mode == O_TEXT)
3219 {
3220 rd_mode = "rt";
3221 wr_mode = "wt";
3222 }
3223 else
3224 {
3225 rd_mode = "rb";
3226 wr_mode = "wb";
3227 }
3228
3229 /* prepare shell references */
3230 if ((shell = getenv("EMXSHELL")) == NULL)
3231 if ((shell = getenv("COMSPEC")) == NULL)
3232 {
3233 errno = ENOENT;
3234 return posix_error();
3235 }
3236
3237 sh_name = _getname(shell);
3238 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3239 opt = "/c";
3240 else
3241 opt = "-c";
3242
3243 /* save current stdio fds + their flags, and set not inheritable */
3244 i = pipe_err = 0;
3245 while (pipe_err >= 0 && i < 3)
3246 {
3247 pipe_err = stdio[i].handle = dup(i);
3248 stdio[i].flags = fcntl(i, F_GETFD, 0);
3249 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3250 i++;
3251 }
3252 if (pipe_err < 0)
3253 {
3254 /* didn't get them all saved - clean up and bail out */
3255 int saved_err = errno;
3256 while (i-- > 0)
3257 {
3258 close(stdio[i].handle);
3259 }
3260 errno = saved_err;
3261 return posix_error();
3262 }
3263
3264 /* create pipe ends */
3265 file_count = 2;
3266 if (n == POPEN_3)
3267 file_count = 3;
3268 i = pipe_err = 0;
3269 while ((pipe_err == 0) && (i < file_count))
3270 pipe_err = pipe((int *)&p_fd[i++]);
3271 if (pipe_err < 0)
3272 {
3273 /* didn't get them all made - clean up and bail out */
3274 while (i-- > 0)
3275 {
3276 close(p_fd[i].wr);
3277 close(p_fd[i].rd);
3278 }
3279 errno = EPIPE;
3280 return posix_error();
3281 }
3282
3283 /* change the actual standard IO streams over temporarily,
3284 * making the retained pipe ends non-inheritable
3285 */
3286 pipe_err = 0;
3287
3288 /* - stdin */
3289 if (dup2(p_fd[0].rd, 0) == 0)
3290 {
3291 close(p_fd[0].rd);
3292 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3293 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3294 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3295 {
3296 close(p_fd[0].wr);
3297 pipe_err = -1;
3298 }
3299 }
3300 else
3301 {
3302 pipe_err = -1;
3303 }
3304
3305 /* - stdout */
3306 if (pipe_err == 0)
3307 {
3308 if (dup2(p_fd[1].wr, 1) == 1)
3309 {
3310 close(p_fd[1].wr);
3311 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3312 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3313 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3314 {
3315 close(p_fd[1].rd);
3316 pipe_err = -1;
3317 }
3318 }
3319 else
3320 {
3321 pipe_err = -1;
3322 }
3323 }
3324
3325 /* - stderr, as required */
3326 if (pipe_err == 0)
3327 switch (n)
3328 {
3329 case POPEN_3:
3330 {
3331 if (dup2(p_fd[2].wr, 2) == 2)
3332 {
3333 close(p_fd[2].wr);
3334 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3335 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3336 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3337 {
3338 close(p_fd[2].rd);
3339 pipe_err = -1;
3340 }
3341 }
3342 else
3343 {
3344 pipe_err = -1;
3345 }
3346 break;
3347 }
3348
3349 case POPEN_4:
3350 {
3351 if (dup2(1, 2) != 2)
3352 {
3353 pipe_err = -1;
3354 }
3355 break;
3356 }
3357 }
3358
3359 /* spawn the child process */
3360 if (pipe_err == 0)
3361 {
3362 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3363 if (pipe_pid == -1)
3364 {
3365 pipe_err = -1;
3366 }
3367 else
3368 {
3369 /* save the PID into the FILE structure
3370 * NOTE: this implementation doesn't actually
3371 * take advantage of this, but do it for
3372 * completeness - AIM Apr01
3373 */
3374 for (i = 0; i < file_count; i++)
3375 p_s[i]->_pid = pipe_pid;
3376 }
3377 }
3378
3379 /* reset standard IO to normal */
3380 for (i = 0; i < 3; i++)
3381 {
3382 dup2(stdio[i].handle, i);
3383 fcntl(i, F_SETFD, stdio[i].flags);
3384 close(stdio[i].handle);
3385 }
3386
3387 /* if any remnant problems, clean up and bail out */
3388 if (pipe_err < 0)
3389 {
3390 for (i = 0; i < 3; i++)
3391 {
3392 close(p_fd[i].rd);
3393 close(p_fd[i].wr);
3394 }
3395 errno = EPIPE;
3396 return posix_error_with_filename(cmdstring);
3397 }
3398
3399 /* build tuple of file objects to return */
3400 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3401 PyFile_SetBufSize(p_f[0], bufsize);
3402 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3403 PyFile_SetBufSize(p_f[1], bufsize);
3404 if (n == POPEN_3)
3405 {
3406 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3407 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003408 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003409 }
3410 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003411 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003412
3413 /*
3414 * Insert the files we've created into the process dictionary
3415 * all referencing the list with the process handle and the
3416 * initial number of files (see description below in _PyPclose).
3417 * Since if _PyPclose later tried to wait on a process when all
3418 * handles weren't closed, it could create a deadlock with the
3419 * child, we spend some energy here to try to ensure that we
3420 * either insert all file handles into the dictionary or none
3421 * at all. It's a little clumsy with the various popen modes
3422 * and variable number of files involved.
3423 */
3424 if (!_PyPopenProcs)
3425 {
3426 _PyPopenProcs = PyDict_New();
3427 }
3428
3429 if (_PyPopenProcs)
3430 {
3431 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3432 int ins_rc[3];
3433
3434 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3435 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3436
3437 procObj = PyList_New(2);
3438 pidObj = PyInt_FromLong((long) pipe_pid);
3439 intObj = PyInt_FromLong((long) file_count);
3440
3441 if (procObj && pidObj && intObj)
3442 {
3443 PyList_SetItem(procObj, 0, pidObj);
3444 PyList_SetItem(procObj, 1, intObj);
3445
3446 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3447 if (fileObj[0])
3448 {
3449 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3450 fileObj[0],
3451 procObj);
3452 }
3453 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3454 if (fileObj[1])
3455 {
3456 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3457 fileObj[1],
3458 procObj);
3459 }
3460 if (file_count >= 3)
3461 {
3462 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3463 if (fileObj[2])
3464 {
3465 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3466 fileObj[2],
3467 procObj);
3468 }
3469 }
3470
3471 if (ins_rc[0] < 0 || !fileObj[0] ||
3472 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3473 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3474 {
3475 /* Something failed - remove any dictionary
3476 * entries that did make it.
3477 */
3478 if (!ins_rc[0] && fileObj[0])
3479 {
3480 PyDict_DelItem(_PyPopenProcs,
3481 fileObj[0]);
3482 }
3483 if (!ins_rc[1] && fileObj[1])
3484 {
3485 PyDict_DelItem(_PyPopenProcs,
3486 fileObj[1]);
3487 }
3488 if (!ins_rc[2] && fileObj[2])
3489 {
3490 PyDict_DelItem(_PyPopenProcs,
3491 fileObj[2]);
3492 }
3493 }
3494 }
Tim Peters11b23062003-04-23 02:39:17 +00003495
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003496 /*
3497 * Clean up our localized references for the dictionary keys
3498 * and value since PyDict_SetItem will Py_INCREF any copies
3499 * that got placed in the dictionary.
3500 */
3501 Py_XDECREF(procObj);
3502 Py_XDECREF(fileObj[0]);
3503 Py_XDECREF(fileObj[1]);
3504 Py_XDECREF(fileObj[2]);
3505 }
3506
3507 /* Child is launched. */
3508 return f;
3509}
3510
3511/*
3512 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3513 * exit code for the child process and return as a result of the close.
3514 *
3515 * This function uses the _PyPopenProcs dictionary in order to map the
3516 * input file pointer to information about the process that was
3517 * originally created by the popen* call that created the file pointer.
3518 * The dictionary uses the file pointer as a key (with one entry
3519 * inserted for each file returned by the original popen* call) and a
3520 * single list object as the value for all files from a single call.
3521 * The list object contains the Win32 process handle at [0], and a file
3522 * count at [1], which is initialized to the total number of file
3523 * handles using that list.
3524 *
3525 * This function closes whichever handle it is passed, and decrements
3526 * the file count in the dictionary for the process handle pointed to
3527 * by this file. On the last close (when the file count reaches zero),
3528 * this function will wait for the child process and then return its
3529 * exit code as the result of the close() operation. This permits the
3530 * files to be closed in any order - it is always the close() of the
3531 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003532 *
3533 * NOTE: This function is currently called with the GIL released.
3534 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003535 */
3536
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003537static int _PyPclose(FILE *file)
3538{
3539 int result;
3540 int exit_code;
3541 int pipe_pid;
3542 PyObject *procObj, *pidObj, *intObj, *fileObj;
3543 int file_count;
3544#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003545 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003546#endif
3547
3548 /* Close the file handle first, to ensure it can't block the
3549 * child from exiting if it's the last handle.
3550 */
3551 result = fclose(file);
3552
3553#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003554 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003555#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003556 if (_PyPopenProcs)
3557 {
3558 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3559 (procObj = PyDict_GetItem(_PyPopenProcs,
3560 fileObj)) != NULL &&
3561 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3562 (intObj = PyList_GetItem(procObj,1)) != NULL)
3563 {
3564 pipe_pid = (int) PyInt_AsLong(pidObj);
3565 file_count = (int) PyInt_AsLong(intObj);
3566
3567 if (file_count > 1)
3568 {
3569 /* Still other files referencing process */
3570 file_count--;
3571 PyList_SetItem(procObj,1,
3572 PyInt_FromLong((long) file_count));
3573 }
3574 else
3575 {
3576 /* Last file for this process */
3577 if (result != EOF &&
3578 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3579 {
3580 /* extract exit status */
3581 if (WIFEXITED(exit_code))
3582 {
3583 result = WEXITSTATUS(exit_code);
3584 }
3585 else
3586 {
3587 errno = EPIPE;
3588 result = -1;
3589 }
3590 }
3591 else
3592 {
3593 /* Indicate failure - this will cause the file object
3594 * to raise an I/O error and translate the last
3595 * error code from errno. We do have a problem with
3596 * last errors that overlap the normal errno table,
3597 * but that's a consistent problem with the file object.
3598 */
3599 result = -1;
3600 }
3601 }
3602
3603 /* Remove this file pointer from dictionary */
3604 PyDict_DelItem(_PyPopenProcs, fileObj);
3605
3606 if (PyDict_Size(_PyPopenProcs) == 0)
3607 {
3608 Py_DECREF(_PyPopenProcs);
3609 _PyPopenProcs = NULL;
3610 }
3611
3612 } /* if object retrieval ok */
3613
3614 Py_XDECREF(fileObj);
3615 } /* if _PyPopenProcs */
3616
3617#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003618 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003619#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003620 return result;
3621}
3622
3623#endif /* PYCC_??? */
3624
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003625#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003626
3627/*
3628 * Portable 'popen' replacement for Win32.
3629 *
3630 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3631 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003632 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003633 */
3634
3635#include <malloc.h>
3636#include <io.h>
3637#include <fcntl.h>
3638
3639/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3640#define POPEN_1 1
3641#define POPEN_2 2
3642#define POPEN_3 3
3643#define POPEN_4 4
3644
3645static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003646static int _PyPclose(FILE *file);
3647
3648/*
3649 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003650 * for use when retrieving the process exit code. See _PyPclose() below
3651 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003652 */
3653static PyObject *_PyPopenProcs = NULL;
3654
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003655
3656/* popen that works from a GUI.
3657 *
3658 * The result of this function is a pipe (file) connected to the
3659 * processes stdin or stdout, depending on the requested mode.
3660 */
3661
3662static PyObject *
3663posix_popen(PyObject *self, PyObject *args)
3664{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00003665 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003666 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003667
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003668 char *cmdstring;
3669 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003670 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003671 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003672 return NULL;
3673
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003674 if (*mode == 'r')
3675 tm = _O_RDONLY;
3676 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003677 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003678 return NULL;
3679 } else
3680 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003681
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003682 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003683 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003684 return NULL;
3685 }
3686
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003687 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003688 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003689 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003690 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003691 else
3692 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3693
3694 return f;
3695}
3696
3697/* Variation on win32pipe.popen
3698 *
3699 * The result of this function is a pipe (file) connected to the
3700 * process's stdin, and a pipe connected to the process's stdout.
3701 */
3702
3703static PyObject *
3704win32_popen2(PyObject *self, PyObject *args)
3705{
3706 PyObject *f;
3707 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003708
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003709 char *cmdstring;
3710 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003711 int bufsize = -1;
3712 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003713 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003714
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003715 if (*mode == 't')
3716 tm = _O_TEXT;
3717 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003718 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003719 return NULL;
3720 } else
3721 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003722
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003723 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003724 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003725 return NULL;
3726 }
3727
3728 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003729
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003730 return f;
3731}
3732
3733/*
3734 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003735 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003736 * The result of this function is 3 pipes - the process's stdin,
3737 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003738 */
3739
3740static PyObject *
3741win32_popen3(PyObject *self, PyObject *args)
3742{
3743 PyObject *f;
3744 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003745
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003746 char *cmdstring;
3747 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003748 int bufsize = -1;
3749 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003750 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003751
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003752 if (*mode == 't')
3753 tm = _O_TEXT;
3754 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003755 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003756 return NULL;
3757 } else
3758 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003759
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003760 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003761 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003762 return NULL;
3763 }
3764
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003765 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003766
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003767 return f;
3768}
3769
3770/*
3771 * Variation on win32pipe.popen
3772 *
Tim Peters5aa91602002-01-30 05:46:57 +00003773 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003774 * and stdout+stderr combined as a single pipe.
3775 */
3776
3777static PyObject *
3778win32_popen4(PyObject *self, PyObject *args)
3779{
3780 PyObject *f;
3781 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003782
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003783 char *cmdstring;
3784 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003785 int bufsize = -1;
3786 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003787 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003788
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003789 if (*mode == 't')
3790 tm = _O_TEXT;
3791 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003792 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003793 return NULL;
3794 } else
3795 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003796
3797 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003798 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003799 return NULL;
3800 }
3801
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003802 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003803
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003804 return f;
3805}
3806
Mark Hammond08501372001-01-31 07:30:29 +00003807static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003808_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003809 HANDLE hStdin,
3810 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003811 HANDLE hStderr,
3812 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003813{
3814 PROCESS_INFORMATION piProcInfo;
3815 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003816 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003817 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003818 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003819 int i;
3820 int x;
3821
3822 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003823 char *comshell;
3824
Tim Peters92e4dd82002-10-05 01:47:34 +00003825 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003826 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3827 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003828
3829 /* Explicitly check if we are using COMMAND.COM. If we are
3830 * then use the w9xpopen hack.
3831 */
3832 comshell = s1 + x;
3833 while (comshell >= s1 && *comshell != '\\')
3834 --comshell;
3835 ++comshell;
3836
3837 if (GetVersion() < 0x80000000 &&
3838 _stricmp(comshell, "command.com") != 0) {
3839 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003840 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003841 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003842 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003843 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003844 }
3845 else {
3846 /*
Tim Peters402d5982001-08-27 06:37:48 +00003847 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3848 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003849 */
Mark Hammond08501372001-01-31 07:30:29 +00003850 char modulepath[_MAX_PATH];
3851 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003852 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3853 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003854 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003855 x = i+1;
3856 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003857 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003858 strncat(modulepath,
3859 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003860 (sizeof(modulepath)/sizeof(modulepath[0]))
3861 -strlen(modulepath));
3862 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003863 /* Eeek - file-not-found - possibly an embedding
3864 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003865 */
Tim Peters5aa91602002-01-30 05:46:57 +00003866 strncpy(modulepath,
3867 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003868 sizeof(modulepath)/sizeof(modulepath[0]));
3869 if (modulepath[strlen(modulepath)-1] != '\\')
3870 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003871 strncat(modulepath,
3872 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003873 (sizeof(modulepath)/sizeof(modulepath[0]))
3874 -strlen(modulepath));
3875 /* No where else to look - raise an easily identifiable
3876 error, rather than leaving Windows to report
3877 "file not found" - as the user is probably blissfully
3878 unaware this shim EXE is used, and it will confuse them.
3879 (well, it confused me for a while ;-)
3880 */
3881 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003882 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003883 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003884 "for popen to work with your shell "
3885 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003886 szConsoleSpawn);
3887 return FALSE;
3888 }
3889 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003890 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003891 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003892 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003893
Tim Peters92e4dd82002-10-05 01:47:34 +00003894 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003895 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003896 /* To maintain correct argument passing semantics,
3897 we pass the command-line as it stands, and allow
3898 quoting to be applied. w9xpopen.exe will then
3899 use its argv vector, and re-quote the necessary
3900 args for the ultimate child process.
3901 */
Tim Peters75cdad52001-11-28 22:07:30 +00003902 PyOS_snprintf(
3903 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003904 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003905 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003906 s1,
3907 s3,
3908 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003909 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00003910 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003911 dialog:
3912 "Your program accessed mem currently in use at xxx"
3913 and a hopeful warning about the stability of your
3914 system.
3915 Cost is Ctrl+C wont kill children, but anyone
3916 who cares can have a go!
3917 */
3918 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003919 }
3920 }
3921
3922 /* Could be an else here to try cmd.exe / command.com in the path
3923 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003924 else {
Tim Peters402d5982001-08-27 06:37:48 +00003925 PyErr_SetString(PyExc_RuntimeError,
3926 "Cannot locate a COMSPEC environment variable to "
3927 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003928 return FALSE;
3929 }
Tim Peters5aa91602002-01-30 05:46:57 +00003930
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003931 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3932 siStartInfo.cb = sizeof(STARTUPINFO);
3933 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3934 siStartInfo.hStdInput = hStdin;
3935 siStartInfo.hStdOutput = hStdout;
3936 siStartInfo.hStdError = hStderr;
3937 siStartInfo.wShowWindow = SW_HIDE;
3938
3939 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003940 s2,
3941 NULL,
3942 NULL,
3943 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003944 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003945 NULL,
3946 NULL,
3947 &siStartInfo,
3948 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003949 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003950 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003951
Mark Hammondb37a3732000-08-14 04:47:33 +00003952 /* Return process handle */
3953 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003954 return TRUE;
3955 }
Tim Peters402d5982001-08-27 06:37:48 +00003956 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003957 return FALSE;
3958}
3959
3960/* The following code is based off of KB: Q190351 */
3961
3962static PyObject *
3963_PyPopen(char *cmdstring, int mode, int n)
3964{
3965 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3966 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003967 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003968
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003969 SECURITY_ATTRIBUTES saAttr;
3970 BOOL fSuccess;
3971 int fd1, fd2, fd3;
3972 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003973 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003974 PyObject *f;
3975
3976 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3977 saAttr.bInheritHandle = TRUE;
3978 saAttr.lpSecurityDescriptor = NULL;
3979
3980 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3981 return win32_error("CreatePipe", NULL);
3982
3983 /* Create new output read handle and the input write handle. Set
3984 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00003985 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003986 * being created. */
3987 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003988 GetCurrentProcess(), &hChildStdinWrDup, 0,
3989 FALSE,
3990 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003991 if (!fSuccess)
3992 return win32_error("DuplicateHandle", NULL);
3993
3994 /* Close the inheritable version of ChildStdin
3995 that we're using. */
3996 CloseHandle(hChildStdinWr);
3997
3998 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3999 return win32_error("CreatePipe", NULL);
4000
4001 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004002 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4003 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004004 if (!fSuccess)
4005 return win32_error("DuplicateHandle", NULL);
4006
4007 /* Close the inheritable version of ChildStdout
4008 that we're using. */
4009 CloseHandle(hChildStdoutRd);
4010
4011 if (n != POPEN_4) {
4012 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4013 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004014 fSuccess = DuplicateHandle(GetCurrentProcess(),
4015 hChildStderrRd,
4016 GetCurrentProcess(),
4017 &hChildStderrRdDup, 0,
4018 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004019 if (!fSuccess)
4020 return win32_error("DuplicateHandle", NULL);
4021 /* Close the inheritable version of ChildStdErr that we're using. */
4022 CloseHandle(hChildStderrRd);
4023 }
Tim Peters5aa91602002-01-30 05:46:57 +00004024
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004025 switch (n) {
4026 case POPEN_1:
4027 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4028 case _O_WRONLY | _O_TEXT:
4029 /* Case for writing to child Stdin in text mode. */
4030 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4031 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004032 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004033 PyFile_SetBufSize(f, 0);
4034 /* We don't care about these pipes anymore, so close them. */
4035 CloseHandle(hChildStdoutRdDup);
4036 CloseHandle(hChildStderrRdDup);
4037 break;
4038
4039 case _O_RDONLY | _O_TEXT:
4040 /* Case for reading from child Stdout in text mode. */
4041 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4042 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004043 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004044 PyFile_SetBufSize(f, 0);
4045 /* We don't care about these pipes anymore, so close them. */
4046 CloseHandle(hChildStdinWrDup);
4047 CloseHandle(hChildStderrRdDup);
4048 break;
4049
4050 case _O_RDONLY | _O_BINARY:
4051 /* Case for readinig from child Stdout in binary mode. */
4052 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4053 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004054 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004055 PyFile_SetBufSize(f, 0);
4056 /* We don't care about these pipes anymore, so close them. */
4057 CloseHandle(hChildStdinWrDup);
4058 CloseHandle(hChildStderrRdDup);
4059 break;
4060
4061 case _O_WRONLY | _O_BINARY:
4062 /* Case for writing to child Stdin in binary mode. */
4063 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4064 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004065 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004066 PyFile_SetBufSize(f, 0);
4067 /* We don't care about these pipes anymore, so close them. */
4068 CloseHandle(hChildStdoutRdDup);
4069 CloseHandle(hChildStderrRdDup);
4070 break;
4071 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004072 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004073 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004074
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004075 case POPEN_2:
4076 case POPEN_4:
4077 {
4078 char *m1, *m2;
4079 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004080
Tim Peters7dca21e2002-08-19 00:42:29 +00004081 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004082 m1 = "r";
4083 m2 = "w";
4084 } else {
4085 m1 = "rb";
4086 m2 = "wb";
4087 }
4088
4089 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4090 f1 = _fdopen(fd1, m2);
4091 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4092 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004093 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004094 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004095 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004096 PyFile_SetBufSize(p2, 0);
4097
4098 if (n != 4)
4099 CloseHandle(hChildStderrRdDup);
4100
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004101 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004102 Py_XDECREF(p1);
4103 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004104 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004105 break;
4106 }
Tim Peters5aa91602002-01-30 05:46:57 +00004107
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004108 case POPEN_3:
4109 {
4110 char *m1, *m2;
4111 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004112
Tim Peters7dca21e2002-08-19 00:42:29 +00004113 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004114 m1 = "r";
4115 m2 = "w";
4116 } else {
4117 m1 = "rb";
4118 m2 = "wb";
4119 }
4120
4121 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4122 f1 = _fdopen(fd1, m2);
4123 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4124 f2 = _fdopen(fd2, m1);
4125 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4126 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004127 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004128 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4129 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004130 PyFile_SetBufSize(p1, 0);
4131 PyFile_SetBufSize(p2, 0);
4132 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004133 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004134 Py_XDECREF(p1);
4135 Py_XDECREF(p2);
4136 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004137 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004138 break;
4139 }
4140 }
4141
4142 if (n == POPEN_4) {
4143 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004144 hChildStdinRd,
4145 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004146 hChildStdoutWr,
4147 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004148 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004149 }
4150 else {
4151 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004152 hChildStdinRd,
4153 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004154 hChildStderrWr,
4155 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004156 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004157 }
4158
Mark Hammondb37a3732000-08-14 04:47:33 +00004159 /*
4160 * Insert the files we've created into the process dictionary
4161 * all referencing the list with the process handle and the
4162 * initial number of files (see description below in _PyPclose).
4163 * Since if _PyPclose later tried to wait on a process when all
4164 * handles weren't closed, it could create a deadlock with the
4165 * child, we spend some energy here to try to ensure that we
4166 * either insert all file handles into the dictionary or none
4167 * at all. It's a little clumsy with the various popen modes
4168 * and variable number of files involved.
4169 */
4170 if (!_PyPopenProcs) {
4171 _PyPopenProcs = PyDict_New();
4172 }
4173
4174 if (_PyPopenProcs) {
4175 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4176 int ins_rc[3];
4177
4178 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4179 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4180
4181 procObj = PyList_New(2);
4182 hProcessObj = PyLong_FromVoidPtr(hProcess);
4183 intObj = PyInt_FromLong(file_count);
4184
4185 if (procObj && hProcessObj && intObj) {
4186 PyList_SetItem(procObj,0,hProcessObj);
4187 PyList_SetItem(procObj,1,intObj);
4188
4189 fileObj[0] = PyLong_FromVoidPtr(f1);
4190 if (fileObj[0]) {
4191 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4192 fileObj[0],
4193 procObj);
4194 }
4195 if (file_count >= 2) {
4196 fileObj[1] = PyLong_FromVoidPtr(f2);
4197 if (fileObj[1]) {
4198 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4199 fileObj[1],
4200 procObj);
4201 }
4202 }
4203 if (file_count >= 3) {
4204 fileObj[2] = PyLong_FromVoidPtr(f3);
4205 if (fileObj[2]) {
4206 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4207 fileObj[2],
4208 procObj);
4209 }
4210 }
4211
4212 if (ins_rc[0] < 0 || !fileObj[0] ||
4213 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4214 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4215 /* Something failed - remove any dictionary
4216 * entries that did make it.
4217 */
4218 if (!ins_rc[0] && fileObj[0]) {
4219 PyDict_DelItem(_PyPopenProcs,
4220 fileObj[0]);
4221 }
4222 if (!ins_rc[1] && fileObj[1]) {
4223 PyDict_DelItem(_PyPopenProcs,
4224 fileObj[1]);
4225 }
4226 if (!ins_rc[2] && fileObj[2]) {
4227 PyDict_DelItem(_PyPopenProcs,
4228 fileObj[2]);
4229 }
4230 }
4231 }
Tim Peters5aa91602002-01-30 05:46:57 +00004232
Mark Hammondb37a3732000-08-14 04:47:33 +00004233 /*
4234 * Clean up our localized references for the dictionary keys
4235 * and value since PyDict_SetItem will Py_INCREF any copies
4236 * that got placed in the dictionary.
4237 */
4238 Py_XDECREF(procObj);
4239 Py_XDECREF(fileObj[0]);
4240 Py_XDECREF(fileObj[1]);
4241 Py_XDECREF(fileObj[2]);
4242 }
4243
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004244 /* Child is launched. Close the parents copy of those pipe
4245 * handles that only the child should have open. You need to
4246 * make sure that no handles to the write end of the output pipe
4247 * are maintained in this process or else the pipe will not close
4248 * when the child process exits and the ReadFile will hang. */
4249
4250 if (!CloseHandle(hChildStdinRd))
4251 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004252
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004253 if (!CloseHandle(hChildStdoutWr))
4254 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004255
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004256 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4257 return win32_error("CloseHandle", NULL);
4258
4259 return f;
4260}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004261
4262/*
4263 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4264 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004265 *
4266 * This function uses the _PyPopenProcs dictionary in order to map the
4267 * input file pointer to information about the process that was
4268 * originally created by the popen* call that created the file pointer.
4269 * The dictionary uses the file pointer as a key (with one entry
4270 * inserted for each file returned by the original popen* call) and a
4271 * single list object as the value for all files from a single call.
4272 * The list object contains the Win32 process handle at [0], and a file
4273 * count at [1], which is initialized to the total number of file
4274 * handles using that list.
4275 *
4276 * This function closes whichever handle it is passed, and decrements
4277 * the file count in the dictionary for the process handle pointed to
4278 * by this file. On the last close (when the file count reaches zero),
4279 * this function will wait for the child process and then return its
4280 * exit code as the result of the close() operation. This permits the
4281 * files to be closed in any order - it is always the close() of the
4282 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004283 *
4284 * NOTE: This function is currently called with the GIL released.
4285 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004286 */
Tim Peters736aa322000-09-01 06:51:24 +00004287
Fredrik Lundh56055a42000-07-23 19:47:12 +00004288static int _PyPclose(FILE *file)
4289{
Fredrik Lundh20318932000-07-26 17:29:12 +00004290 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004291 DWORD exit_code;
4292 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004293 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4294 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004295#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004296 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004297#endif
4298
Fredrik Lundh20318932000-07-26 17:29:12 +00004299 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004300 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004301 */
4302 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004303#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004304 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004305#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004306 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004307 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4308 (procObj = PyDict_GetItem(_PyPopenProcs,
4309 fileObj)) != NULL &&
4310 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4311 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4312
4313 hProcess = PyLong_AsVoidPtr(hProcessObj);
4314 file_count = PyInt_AsLong(intObj);
4315
4316 if (file_count > 1) {
4317 /* Still other files referencing process */
4318 file_count--;
4319 PyList_SetItem(procObj,1,
4320 PyInt_FromLong(file_count));
4321 } else {
4322 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004323 if (result != EOF &&
4324 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4325 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004326 /* Possible truncation here in 16-bit environments, but
4327 * real exit codes are just the lower byte in any event.
4328 */
4329 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004330 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004331 /* Indicate failure - this will cause the file object
4332 * to raise an I/O error and translate the last Win32
4333 * error code from errno. We do have a problem with
4334 * last errors that overlap the normal errno table,
4335 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004336 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004337 if (result != EOF) {
4338 /* If the error wasn't from the fclose(), then
4339 * set errno for the file object error handling.
4340 */
4341 errno = GetLastError();
4342 }
4343 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004344 }
4345
4346 /* Free up the native handle at this point */
4347 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004348 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004349
Mark Hammondb37a3732000-08-14 04:47:33 +00004350 /* Remove this file pointer from dictionary */
4351 PyDict_DelItem(_PyPopenProcs, fileObj);
4352
4353 if (PyDict_Size(_PyPopenProcs) == 0) {
4354 Py_DECREF(_PyPopenProcs);
4355 _PyPopenProcs = NULL;
4356 }
4357
4358 } /* if object retrieval ok */
4359
4360 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004361 } /* if _PyPopenProcs */
4362
Tim Peters736aa322000-09-01 06:51:24 +00004363#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004364 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004365#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004366 return result;
4367}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004368
4369#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004371posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004372{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004373 char *name;
4374 char *mode = "r";
4375 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004376 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004377 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004378 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004379 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004380 /* Strip mode of binary or text modifiers */
4381 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4382 mode = "r";
4383 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4384 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004385 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004386 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004387 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004388 if (fp == NULL)
4389 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004390 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004391 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004392 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004393 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004394}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004395
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004396#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004397#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004399
Guido van Rossumb6775db1994-08-01 11:34:53 +00004400#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004401PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004402"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004403Set the current process's user id.");
4404
Barry Warsaw53699e91996-12-10 23:23:01 +00004405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004406posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004407{
4408 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004409 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004410 return NULL;
4411 if (setuid(uid) < 0)
4412 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004413 Py_INCREF(Py_None);
4414 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004415}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004416#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004418
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004419#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004420PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004421"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004422Set the current process's effective user id.");
4423
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004424static PyObject *
4425posix_seteuid (PyObject *self, PyObject *args)
4426{
4427 int euid;
4428 if (!PyArg_ParseTuple(args, "i", &euid)) {
4429 return NULL;
4430 } else if (seteuid(euid) < 0) {
4431 return posix_error();
4432 } else {
4433 Py_INCREF(Py_None);
4434 return Py_None;
4435 }
4436}
4437#endif /* HAVE_SETEUID */
4438
4439#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004440PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004441"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442Set the current process's effective group id.");
4443
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004444static PyObject *
4445posix_setegid (PyObject *self, PyObject *args)
4446{
4447 int egid;
4448 if (!PyArg_ParseTuple(args, "i", &egid)) {
4449 return NULL;
4450 } else if (setegid(egid) < 0) {
4451 return posix_error();
4452 } else {
4453 Py_INCREF(Py_None);
4454 return Py_None;
4455 }
4456}
4457#endif /* HAVE_SETEGID */
4458
4459#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004460PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004461"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004462Set the current process's real and effective user ids.");
4463
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004464static PyObject *
4465posix_setreuid (PyObject *self, PyObject *args)
4466{
4467 int ruid, euid;
4468 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4469 return NULL;
4470 } else if (setreuid(ruid, euid) < 0) {
4471 return posix_error();
4472 } else {
4473 Py_INCREF(Py_None);
4474 return Py_None;
4475 }
4476}
4477#endif /* HAVE_SETREUID */
4478
4479#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004480PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004481"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004482Set the current process's real and effective group ids.");
4483
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004484static PyObject *
4485posix_setregid (PyObject *self, PyObject *args)
4486{
4487 int rgid, egid;
4488 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4489 return NULL;
4490 } else if (setregid(rgid, egid) < 0) {
4491 return posix_error();
4492 } else {
4493 Py_INCREF(Py_None);
4494 return Py_None;
4495 }
4496}
4497#endif /* HAVE_SETREGID */
4498
Guido van Rossumb6775db1994-08-01 11:34:53 +00004499#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004500PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004501"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004502Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004503
Barry Warsaw53699e91996-12-10 23:23:01 +00004504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004505posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004506{
4507 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004508 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004509 return NULL;
4510 if (setgid(gid) < 0)
4511 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004512 Py_INCREF(Py_None);
4513 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004514}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004515#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004516
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004517#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004518PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004519"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004520Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004521
4522static PyObject *
4523posix_setgroups(PyObject *self, PyObject *args)
4524{
4525 PyObject *groups;
4526 int i, len;
4527 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004528
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004529 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4530 return NULL;
4531 if (!PySequence_Check(groups)) {
4532 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4533 return NULL;
4534 }
4535 len = PySequence_Size(groups);
4536 if (len > MAX_GROUPS) {
4537 PyErr_SetString(PyExc_ValueError, "too many groups");
4538 return NULL;
4539 }
4540 for(i = 0; i < len; i++) {
4541 PyObject *elem;
4542 elem = PySequence_GetItem(groups, i);
4543 if (!elem)
4544 return NULL;
4545 if (!PyInt_Check(elem)) {
4546 PyErr_SetString(PyExc_TypeError,
4547 "groups must be integers");
4548 Py_DECREF(elem);
4549 return NULL;
4550 }
4551 /* XXX: check that value fits into gid_t. */
4552 grouplist[i] = PyInt_AsLong(elem);
4553 Py_DECREF(elem);
4554 }
4555
4556 if (setgroups(len, grouplist) < 0)
4557 return posix_error();
4558 Py_INCREF(Py_None);
4559 return Py_None;
4560}
4561#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004562
Guido van Rossumb6775db1994-08-01 11:34:53 +00004563#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004564PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004565"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004566Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004567
Barry Warsaw53699e91996-12-10 23:23:01 +00004568static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004569posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004570{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004571 int pid, options;
4572#ifdef UNION_WAIT
4573 union wait status;
4574#define status_i (status.w_status)
4575#else
4576 int status;
4577#define status_i status
4578#endif
4579 status_i = 0;
4580
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004581 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004582 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004583 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004584 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004585 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004586 if (pid == -1)
4587 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004588 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004589 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004590}
4591
Tim Petersab034fa2002-02-01 11:27:43 +00004592#elif defined(HAVE_CWAIT)
4593
4594/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004595PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004596"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004597"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004598
4599static PyObject *
4600posix_waitpid(PyObject *self, PyObject *args)
4601{
4602 int pid, options;
4603 int status;
4604
4605 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4606 return NULL;
4607 Py_BEGIN_ALLOW_THREADS
4608 pid = _cwait(&status, pid, options);
4609 Py_END_ALLOW_THREADS
4610 if (pid == -1)
4611 return posix_error();
4612 else
4613 /* shift the status left a byte so this is more like the
4614 POSIX waitpid */
4615 return Py_BuildValue("ii", pid, status << 8);
4616}
4617#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004618
Guido van Rossumad0ee831995-03-01 10:34:45 +00004619#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004620PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004621"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004622Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004623
Barry Warsaw53699e91996-12-10 23:23:01 +00004624static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004625posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004626{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004627 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004628#ifdef UNION_WAIT
4629 union wait status;
4630#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004631#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004632 int status;
4633#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004634#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004635
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004636 status_i = 0;
4637 Py_BEGIN_ALLOW_THREADS
4638 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004639 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004640 if (pid == -1)
4641 return posix_error();
4642 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004643 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004644#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004645}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004646#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004647
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004648
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004649PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004650"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004651Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004652
Barry Warsaw53699e91996-12-10 23:23:01 +00004653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004654posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004655{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004656#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004657 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004658#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004659#ifdef MS_WINDOWS
Mark Hammond7edd0a92003-08-06 02:46:58 +00004660 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", _wstati64);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004661#else
4662 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4663#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004664#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004665}
4666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004667
Guido van Rossumb6775db1994-08-01 11:34:53 +00004668#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004669PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004670"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004671Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004672
Barry Warsaw53699e91996-12-10 23:23:01 +00004673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004674posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004675{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004676 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004677 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004678 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004679 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004680 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004681 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004682 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004683 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004684 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004685 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004686 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004687}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004688#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004689
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004690
Guido van Rossumb6775db1994-08-01 11:34:53 +00004691#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004692PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004693"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004694Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004695
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004696static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004697posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004698{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004699 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004700}
4701#endif /* HAVE_SYMLINK */
4702
4703
4704#ifdef HAVE_TIMES
4705#ifndef HZ
4706#define HZ 60 /* Universal constant :-) */
4707#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004708
Guido van Rossumd48f2521997-12-05 22:19:34 +00004709#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4710static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004711system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004712{
4713 ULONG value = 0;
4714
4715 Py_BEGIN_ALLOW_THREADS
4716 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4717 Py_END_ALLOW_THREADS
4718
4719 return value;
4720}
4721
4722static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004723posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004724{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004725 /* Currently Only Uptime is Provided -- Others Later */
4726 return Py_BuildValue("ddddd",
4727 (double)0 /* t.tms_utime / HZ */,
4728 (double)0 /* t.tms_stime / HZ */,
4729 (double)0 /* t.tms_cutime / HZ */,
4730 (double)0 /* t.tms_cstime / HZ */,
4731 (double)system_uptime() / 1000);
4732}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004733#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004734static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004735posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004736{
4737 struct tms t;
4738 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004739 errno = 0;
4740 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004741 if (c == (clock_t) -1)
4742 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004743 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004744 (double)t.tms_utime / HZ,
4745 (double)t.tms_stime / HZ,
4746 (double)t.tms_cutime / HZ,
4747 (double)t.tms_cstime / HZ,
4748 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004749}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004750#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004751#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004752
4753
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004754#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004755#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004756static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004757posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004758{
4759 FILETIME create, exit, kernel, user;
4760 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004761 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004762 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4763 /* The fields of a FILETIME structure are the hi and lo part
4764 of a 64-bit value expressed in 100 nanosecond units.
4765 1e7 is one second in such units; 1e-7 the inverse.
4766 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4767 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004768 return Py_BuildValue(
4769 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004770 (double)(kernel.dwHighDateTime*429.4967296 +
4771 kernel.dwLowDateTime*1e-7),
4772 (double)(user.dwHighDateTime*429.4967296 +
4773 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004774 (double)0,
4775 (double)0,
4776 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004777}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004778#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004779
4780#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004781PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004782"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004783Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004784#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004786
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004787#ifdef HAVE_GETSID
4788PyDoc_STRVAR(posix_getsid__doc__,
4789"getsid(pid) -> sid\n\n\
4790Call the system call getsid().");
4791
4792static PyObject *
4793posix_getsid(PyObject *self, PyObject *args)
4794{
4795 int pid, sid;
4796 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4797 return NULL;
4798 sid = getsid(pid);
4799 if (sid < 0)
4800 return posix_error();
4801 return PyInt_FromLong((long)sid);
4802}
4803#endif /* HAVE_GETSID */
4804
4805
Guido van Rossumb6775db1994-08-01 11:34:53 +00004806#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004807PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004808"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004809Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004810
Barry Warsaw53699e91996-12-10 23:23:01 +00004811static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004812posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004813{
Guido van Rossum687dd131993-05-17 08:34:16 +00004814 if (setsid() < 0)
4815 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004816 Py_INCREF(Py_None);
4817 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004818}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004819#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004820
Guido van Rossumb6775db1994-08-01 11:34:53 +00004821#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004822PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004823"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004824Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004825
Barry Warsaw53699e91996-12-10 23:23:01 +00004826static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004827posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004828{
4829 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004830 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004831 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004832 if (setpgid(pid, pgrp) < 0)
4833 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004834 Py_INCREF(Py_None);
4835 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004836}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004837#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004839
Guido van Rossumb6775db1994-08-01 11:34:53 +00004840#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004841PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004842"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004843Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004844
Barry Warsaw53699e91996-12-10 23:23:01 +00004845static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004846posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004847{
4848 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004849 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004850 return NULL;
4851 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004852 if (pgid < 0)
4853 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004854 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004855}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004856#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004857
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004858
Guido van Rossumb6775db1994-08-01 11:34:53 +00004859#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004860PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004861"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004862Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004863
Barry Warsaw53699e91996-12-10 23:23:01 +00004864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004865posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004866{
4867 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004868 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004869 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004870 if (tcsetpgrp(fd, pgid) < 0)
4871 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004872 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004873 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004874}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004875#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004876
Guido van Rossum687dd131993-05-17 08:34:16 +00004877/* Functions acting on file descriptors */
4878
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004879PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004880"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004881Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004882
Barry Warsaw53699e91996-12-10 23:23:01 +00004883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004884posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004885{
Mark Hammondef8b6542001-05-13 08:04:26 +00004886 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004887 int flag;
4888 int mode = 0777;
4889 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004890
4891#ifdef MS_WINDOWS
4892 if (unicode_file_names()) {
4893 PyUnicodeObject *po;
4894 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4895 Py_BEGIN_ALLOW_THREADS
4896 /* PyUnicode_AS_UNICODE OK without thread
4897 lock as it is a simple dereference. */
4898 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4899 Py_END_ALLOW_THREADS
4900 if (fd < 0)
4901 return posix_error();
4902 return PyInt_FromLong((long)fd);
4903 }
4904 /* Drop the argument parsing error as narrow strings
4905 are also valid. */
4906 PyErr_Clear();
4907 }
4908#endif
4909
Tim Peters5aa91602002-01-30 05:46:57 +00004910 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004911 Py_FileSystemDefaultEncoding, &file,
4912 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004913 return NULL;
4914
Barry Warsaw53699e91996-12-10 23:23:01 +00004915 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004916 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004917 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004918 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004919 return posix_error_with_allocated_filename(file);
4920 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004921 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004922}
4923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004924
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004925PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004926"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004927Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004928
Barry Warsaw53699e91996-12-10 23:23:01 +00004929static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004930posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004931{
4932 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004933 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004934 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004935 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004936 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004937 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004938 if (res < 0)
4939 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004940 Py_INCREF(Py_None);
4941 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004942}
4943
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004944
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004945PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004946"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004947Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004948
Barry Warsaw53699e91996-12-10 23:23:01 +00004949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004950posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004951{
4952 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004953 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004954 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004955 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004956 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004957 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004958 if (fd < 0)
4959 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004960 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004961}
4962
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004963
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004964PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00004965"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004966Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004967
Barry Warsaw53699e91996-12-10 23:23:01 +00004968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004969posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004970{
4971 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004972 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004973 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004974 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004975 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004976 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004977 if (res < 0)
4978 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004979 Py_INCREF(Py_None);
4980 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004981}
4982
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004983
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004984PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004985"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004986Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004987
Barry Warsaw53699e91996-12-10 23:23:01 +00004988static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004989posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004990{
4991 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004992#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004993 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004994#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004995 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004996#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004997 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004998 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004999 return NULL;
5000#ifdef SEEK_SET
5001 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5002 switch (how) {
5003 case 0: how = SEEK_SET; break;
5004 case 1: how = SEEK_CUR; break;
5005 case 2: how = SEEK_END; break;
5006 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005007#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005008
5009#if !defined(HAVE_LARGEFILE_SUPPORT)
5010 pos = PyInt_AsLong(posobj);
5011#else
5012 pos = PyLong_Check(posobj) ?
5013 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5014#endif
5015 if (PyErr_Occurred())
5016 return NULL;
5017
Barry Warsaw53699e91996-12-10 23:23:01 +00005018 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005019#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005020 res = _lseeki64(fd, pos, how);
5021#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005022 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005023#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005024 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005025 if (res < 0)
5026 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005027
5028#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005029 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005030#else
5031 return PyLong_FromLongLong(res);
5032#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005033}
5034
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005035
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005036PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005037"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005038Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005039
Barry Warsaw53699e91996-12-10 23:23:01 +00005040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005041posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005042{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005043 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005044 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005045 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005046 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005047 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005048 if (buffer == NULL)
5049 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005050 Py_BEGIN_ALLOW_THREADS
5051 n = read(fd, PyString_AsString(buffer), size);
5052 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005053 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005054 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005055 return posix_error();
5056 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005057 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005058 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005059 return buffer;
5060}
5061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005062
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005063PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005064"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005065Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005066
Barry Warsaw53699e91996-12-10 23:23:01 +00005067static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005068posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005069{
5070 int fd, size;
5071 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005072 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005073 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005074 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005075 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005076 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005077 if (size < 0)
5078 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005079 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005080}
5081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005083PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005084"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005085Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005086
Barry Warsaw53699e91996-12-10 23:23:01 +00005087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005088posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005089{
5090 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005091 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005092 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005093 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005094 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005095#ifdef __VMS
5096 /* on OpenVMS we must ensure that all bytes are written to the file */
5097 fsync(fd);
5098#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005099 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005100 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005101 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005102 if (res != 0)
5103 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005104
Fred Drake699f3522000-06-29 21:12:41 +00005105 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005106}
5107
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005108
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005109PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005110"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005111Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005112
Barry Warsaw53699e91996-12-10 23:23:01 +00005113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005114posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005115{
Guido van Rossum687dd131993-05-17 08:34:16 +00005116 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005117 char *mode = "r";
5118 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005119 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005120 PyObject *f;
5121 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005122 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005123
Thomas Heller1f043e22002-11-07 16:00:59 +00005124 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5125 PyErr_Format(PyExc_ValueError,
5126 "invalid file mode '%s'", mode);
5127 return NULL;
5128 }
5129
Barry Warsaw53699e91996-12-10 23:23:01 +00005130 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005131 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005132 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005133 if (fp == NULL)
5134 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005135 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005136 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005137 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005138 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005139}
5140
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005141PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005142"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005143Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005144connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005145
5146static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005147posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005148{
5149 int fd;
5150 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5151 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005152 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005153}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005154
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005155#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005156PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005157"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005158Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005159
Barry Warsaw53699e91996-12-10 23:23:01 +00005160static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005161posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005162{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005163#if defined(PYOS_OS2)
5164 HFILE read, write;
5165 APIRET rc;
5166
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005167 Py_BEGIN_ALLOW_THREADS
5168 rc = DosCreatePipe( &read, &write, 4096);
5169 Py_END_ALLOW_THREADS
5170 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005171 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005172
5173 return Py_BuildValue("(ii)", read, write);
5174#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005175#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005176 int fds[2];
5177 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005178 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005179 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005180 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005181 if (res != 0)
5182 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005183 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005184#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005185 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005186 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005187 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005188 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005189 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005190 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005191 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005192 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005193 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5194 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005195 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005196#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005197#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005198}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005199#endif /* HAVE_PIPE */
5200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005201
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005202#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005203PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005204"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005205Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005206
Barry Warsaw53699e91996-12-10 23:23:01 +00005207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005208posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005209{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005210 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005211 int mode = 0666;
5212 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005213 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005214 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005215 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005216 res = mkfifo(filename, mode);
5217 Py_END_ALLOW_THREADS
5218 if (res < 0)
5219 return posix_error();
5220 Py_INCREF(Py_None);
5221 return Py_None;
5222}
5223#endif
5224
5225
Neal Norwitz11690112002-07-30 01:08:28 +00005226#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005227PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005228"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005229Create a filesystem node (file, device special file or named pipe)\n\
5230named filename. mode specifies both the permissions to use and the\n\
5231type of node to be created, being combined (bitwise OR) with one of\n\
5232S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005233device defines the newly created device special file (probably using\n\
5234os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005235
5236
5237static PyObject *
5238posix_mknod(PyObject *self, PyObject *args)
5239{
5240 char *filename;
5241 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005242 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005243 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005244 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005245 return NULL;
5246 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005247 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005248 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005249 if (res < 0)
5250 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005251 Py_INCREF(Py_None);
5252 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005253}
5254#endif
5255
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005256#ifdef HAVE_DEVICE_MACROS
5257PyDoc_STRVAR(posix_major__doc__,
5258"major(device) -> major number\n\
5259Extracts a device major number from a raw device number.");
5260
5261static PyObject *
5262posix_major(PyObject *self, PyObject *args)
5263{
5264 int device;
5265 if (!PyArg_ParseTuple(args, "i:major", &device))
5266 return NULL;
5267 return PyInt_FromLong((long)major(device));
5268}
5269
5270PyDoc_STRVAR(posix_minor__doc__,
5271"minor(device) -> minor number\n\
5272Extracts a device minor number from a raw device number.");
5273
5274static PyObject *
5275posix_minor(PyObject *self, PyObject *args)
5276{
5277 int device;
5278 if (!PyArg_ParseTuple(args, "i:minor", &device))
5279 return NULL;
5280 return PyInt_FromLong((long)minor(device));
5281}
5282
5283PyDoc_STRVAR(posix_makedev__doc__,
5284"makedev(major, minor) -> device number\n\
5285Composes a raw device number from the major and minor device numbers.");
5286
5287static PyObject *
5288posix_makedev(PyObject *self, PyObject *args)
5289{
5290 int major, minor;
5291 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5292 return NULL;
5293 return PyInt_FromLong((long)makedev(major, minor));
5294}
5295#endif /* device macros */
5296
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005297
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005298#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005299PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005300"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005301Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005302
Barry Warsaw53699e91996-12-10 23:23:01 +00005303static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005304posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005305{
5306 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005307 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005308 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005309 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005310
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005311 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005312 return NULL;
5313
5314#if !defined(HAVE_LARGEFILE_SUPPORT)
5315 length = PyInt_AsLong(lenobj);
5316#else
5317 length = PyLong_Check(lenobj) ?
5318 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5319#endif
5320 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005321 return NULL;
5322
Barry Warsaw53699e91996-12-10 23:23:01 +00005323 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005324 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005325 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005326 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005327 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005328 return NULL;
5329 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005330 Py_INCREF(Py_None);
5331 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005332}
5333#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005334
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005335#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005336PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005337"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005338Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005339
Fred Drake762e2061999-08-26 17:23:54 +00005340/* Save putenv() parameters as values here, so we can collect them when they
5341 * get re-set with another call for the same key. */
5342static PyObject *posix_putenv_garbage;
5343
Tim Peters5aa91602002-01-30 05:46:57 +00005344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005345posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005346{
5347 char *s1, *s2;
5348 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005349 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005350 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005351
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005352 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005353 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005354
5355#if defined(PYOS_OS2)
5356 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5357 APIRET rc;
5358
Guido van Rossumd48f2521997-12-05 22:19:34 +00005359 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5360 if (rc != NO_ERROR)
5361 return os2_error(rc);
5362
5363 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5364 APIRET rc;
5365
Guido van Rossumd48f2521997-12-05 22:19:34 +00005366 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5367 if (rc != NO_ERROR)
5368 return os2_error(rc);
5369 } else {
5370#endif
5371
Fred Drake762e2061999-08-26 17:23:54 +00005372 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005373 len = strlen(s1) + strlen(s2) + 2;
5374 /* len includes space for a trailing \0; the size arg to
5375 PyString_FromStringAndSize does not count that */
5376 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005377 if (newstr == NULL)
5378 return PyErr_NoMemory();
5379 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005380 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005381 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005382 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005383 posix_error();
5384 return NULL;
5385 }
Fred Drake762e2061999-08-26 17:23:54 +00005386 /* Install the first arg and newstr in posix_putenv_garbage;
5387 * this will cause previous value to be collected. This has to
5388 * happen after the real putenv() call because the old value
5389 * was still accessible until then. */
5390 if (PyDict_SetItem(posix_putenv_garbage,
5391 PyTuple_GET_ITEM(args, 0), newstr)) {
5392 /* really not much we can do; just leak */
5393 PyErr_Clear();
5394 }
5395 else {
5396 Py_DECREF(newstr);
5397 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005398
5399#if defined(PYOS_OS2)
5400 }
5401#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005402 Py_INCREF(Py_None);
5403 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005404}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005405#endif /* putenv */
5406
Guido van Rossumc524d952001-10-19 01:31:59 +00005407#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005408PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005409"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005410Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005411
5412static PyObject *
5413posix_unsetenv(PyObject *self, PyObject *args)
5414{
5415 char *s1;
5416
5417 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5418 return NULL;
5419
5420 unsetenv(s1);
5421
5422 /* Remove the key from posix_putenv_garbage;
5423 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005424 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005425 * old value was still accessible until then.
5426 */
5427 if (PyDict_DelItem(posix_putenv_garbage,
5428 PyTuple_GET_ITEM(args, 0))) {
5429 /* really not much we can do; just leak */
5430 PyErr_Clear();
5431 }
5432
5433 Py_INCREF(Py_None);
5434 return Py_None;
5435}
5436#endif /* unsetenv */
5437
Guido van Rossumb6a47161997-09-15 22:54:34 +00005438#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005439PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005440"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005441Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005442
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005444posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005445{
5446 int code;
5447 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005448 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005449 return NULL;
5450 message = strerror(code);
5451 if (message == NULL) {
5452 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005453 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005454 return NULL;
5455 }
5456 return PyString_FromString(message);
5457}
5458#endif /* strerror */
5459
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005460
Guido van Rossumc9641791998-08-04 15:26:23 +00005461#ifdef HAVE_SYS_WAIT_H
5462
Fred Drake106c1a02002-04-23 15:58:02 +00005463#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005464PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005465"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005466Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005467
5468static PyObject *
5469posix_WCOREDUMP(PyObject *self, PyObject *args)
5470{
5471#ifdef UNION_WAIT
5472 union wait status;
5473#define status_i (status.w_status)
5474#else
5475 int status;
5476#define status_i status
5477#endif
5478 status_i = 0;
5479
5480 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5481 {
5482 return NULL;
5483 }
5484
5485 return PyBool_FromLong(WCOREDUMP(status));
5486#undef status_i
5487}
5488#endif /* WCOREDUMP */
5489
5490#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005491PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005492"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005493Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005494job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005495
5496static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005497posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005498{
5499#ifdef UNION_WAIT
5500 union wait status;
5501#define status_i (status.w_status)
5502#else
5503 int status;
5504#define status_i status
5505#endif
5506 status_i = 0;
5507
5508 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5509 {
5510 return NULL;
5511 }
5512
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005513 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005514#undef status_i
5515}
5516#endif /* WIFCONTINUED */
5517
Guido van Rossumc9641791998-08-04 15:26:23 +00005518#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005520"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005521Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005522
5523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005524posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005525{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005526#ifdef UNION_WAIT
5527 union wait status;
5528#define status_i (status.w_status)
5529#else
5530 int status;
5531#define status_i status
5532#endif
5533 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005534
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005535 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005536 {
5537 return NULL;
5538 }
Tim Peters5aa91602002-01-30 05:46:57 +00005539
Fred Drake106c1a02002-04-23 15:58:02 +00005540 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005541#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005542}
5543#endif /* WIFSTOPPED */
5544
5545#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005546PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005547"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005548Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005549
5550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005551posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005552{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005553#ifdef UNION_WAIT
5554 union wait status;
5555#define status_i (status.w_status)
5556#else
5557 int status;
5558#define status_i status
5559#endif
5560 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005561
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005562 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005563 {
5564 return NULL;
5565 }
Tim Peters5aa91602002-01-30 05:46:57 +00005566
Fred Drake106c1a02002-04-23 15:58:02 +00005567 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005568#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005569}
5570#endif /* WIFSIGNALED */
5571
5572#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005573PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005574"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005575Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005576system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005577
5578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005579posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005580{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005581#ifdef UNION_WAIT
5582 union wait status;
5583#define status_i (status.w_status)
5584#else
5585 int status;
5586#define status_i status
5587#endif
5588 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005589
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005590 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005591 {
5592 return NULL;
5593 }
Tim Peters5aa91602002-01-30 05:46:57 +00005594
Fred Drake106c1a02002-04-23 15:58:02 +00005595 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005596#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005597}
5598#endif /* WIFEXITED */
5599
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005600#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005601PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005602"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005603Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005604
5605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005606posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005607{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005608#ifdef UNION_WAIT
5609 union wait status;
5610#define status_i (status.w_status)
5611#else
5612 int status;
5613#define status_i status
5614#endif
5615 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005616
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005617 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005618 {
5619 return NULL;
5620 }
Tim Peters5aa91602002-01-30 05:46:57 +00005621
Guido van Rossumc9641791998-08-04 15:26:23 +00005622 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005623#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005624}
5625#endif /* WEXITSTATUS */
5626
5627#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005628PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005629"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005630Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005631value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005632
5633static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005634posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005635{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005636#ifdef UNION_WAIT
5637 union wait status;
5638#define status_i (status.w_status)
5639#else
5640 int status;
5641#define status_i status
5642#endif
5643 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005644
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005645 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005646 {
5647 return NULL;
5648 }
Tim Peters5aa91602002-01-30 05:46:57 +00005649
Guido van Rossumc9641791998-08-04 15:26:23 +00005650 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005651#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005652}
5653#endif /* WTERMSIG */
5654
5655#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005656PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005657"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005658Return the signal that stopped the process that provided\n\
5659the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005660
5661static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005662posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005663{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005664#ifdef UNION_WAIT
5665 union wait status;
5666#define status_i (status.w_status)
5667#else
5668 int status;
5669#define status_i status
5670#endif
5671 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005672
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005673 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005674 {
5675 return NULL;
5676 }
Tim Peters5aa91602002-01-30 05:46:57 +00005677
Guido van Rossumc9641791998-08-04 15:26:23 +00005678 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005679#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005680}
5681#endif /* WSTOPSIG */
5682
5683#endif /* HAVE_SYS_WAIT_H */
5684
5685
Guido van Rossum94f6f721999-01-06 18:42:14 +00005686#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005687#ifdef _SCO_DS
5688/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5689 needed definitions in sys/statvfs.h */
5690#define _SVID3
5691#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005692#include <sys/statvfs.h>
5693
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005694static PyObject*
5695_pystatvfs_fromstructstatvfs(struct statvfs st) {
5696 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5697 if (v == NULL)
5698 return NULL;
5699
5700#if !defined(HAVE_LARGEFILE_SUPPORT)
5701 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5702 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5703 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5704 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5705 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5706 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5707 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5708 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5709 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5710 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5711#else
5712 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5713 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005714 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005715 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005716 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005717 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005718 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005719 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005720 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005721 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005722 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005723 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005724 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005725 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005726 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5727 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5728#endif
5729
5730 return v;
5731}
5732
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005733PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005734"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005735Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005736
5737static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005738posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005739{
5740 int fd, res;
5741 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005742
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005743 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005744 return NULL;
5745 Py_BEGIN_ALLOW_THREADS
5746 res = fstatvfs(fd, &st);
5747 Py_END_ALLOW_THREADS
5748 if (res != 0)
5749 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005750
5751 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005752}
5753#endif /* HAVE_FSTATVFS */
5754
5755
5756#if defined(HAVE_STATVFS)
5757#include <sys/statvfs.h>
5758
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005759PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005760"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005761Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005762
5763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005764posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005765{
5766 char *path;
5767 int res;
5768 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005769 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005770 return NULL;
5771 Py_BEGIN_ALLOW_THREADS
5772 res = statvfs(path, &st);
5773 Py_END_ALLOW_THREADS
5774 if (res != 0)
5775 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005776
5777 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005778}
5779#endif /* HAVE_STATVFS */
5780
5781
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005782#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005783PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005784"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005785Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005786The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005787or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005788
5789static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005790posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005791{
5792 PyObject *result = NULL;
5793 char *dir = NULL;
5794 char *pfx = NULL;
5795 char *name;
5796
5797 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5798 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005799
5800 if (PyErr_Warn(PyExc_RuntimeWarning,
5801 "tempnam is a potential security risk to your program") < 0)
5802 return NULL;
5803
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005804#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005805 name = _tempnam(dir, pfx);
5806#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005807 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005808#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005809 if (name == NULL)
5810 return PyErr_NoMemory();
5811 result = PyString_FromString(name);
5812 free(name);
5813 return result;
5814}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005815#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005816
5817
5818#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005819PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005820"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005821Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005822
5823static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005824posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005825{
5826 FILE *fp;
5827
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005828 fp = tmpfile();
5829 if (fp == NULL)
5830 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005831 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005832}
5833#endif
5834
5835
5836#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005837PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005838"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005839Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005840
5841static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005842posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005843{
5844 char buffer[L_tmpnam];
5845 char *name;
5846
Skip Montanaro95618b52001-08-18 18:52:10 +00005847 if (PyErr_Warn(PyExc_RuntimeWarning,
5848 "tmpnam is a potential security risk to your program") < 0)
5849 return NULL;
5850
Greg Wardb48bc172000-03-01 21:51:56 +00005851#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005852 name = tmpnam_r(buffer);
5853#else
5854 name = tmpnam(buffer);
5855#endif
5856 if (name == NULL) {
5857 PyErr_SetObject(PyExc_OSError,
5858 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005859#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005860 "unexpected NULL from tmpnam_r"
5861#else
5862 "unexpected NULL from tmpnam"
5863#endif
5864 ));
5865 return NULL;
5866 }
5867 return PyString_FromString(buffer);
5868}
5869#endif
5870
5871
Fred Drakec9680921999-12-13 16:37:25 +00005872/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5873 * It maps strings representing configuration variable names to
5874 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005875 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005876 * rarely-used constants. There are three separate tables that use
5877 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005878 *
5879 * This code is always included, even if none of the interfaces that
5880 * need it are included. The #if hackery needed to avoid it would be
5881 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005882 */
5883struct constdef {
5884 char *name;
5885 long value;
5886};
5887
Fred Drake12c6e2d1999-12-14 21:25:03 +00005888static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005889conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5890 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005891{
5892 if (PyInt_Check(arg)) {
5893 *valuep = PyInt_AS_LONG(arg);
5894 return 1;
5895 }
5896 if (PyString_Check(arg)) {
5897 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005898 size_t lo = 0;
5899 size_t mid;
5900 size_t hi = tablesize;
5901 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005902 char *confname = PyString_AS_STRING(arg);
5903 while (lo < hi) {
5904 mid = (lo + hi) / 2;
5905 cmp = strcmp(confname, table[mid].name);
5906 if (cmp < 0)
5907 hi = mid;
5908 else if (cmp > 0)
5909 lo = mid + 1;
5910 else {
5911 *valuep = table[mid].value;
5912 return 1;
5913 }
5914 }
5915 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5916 }
5917 else
5918 PyErr_SetString(PyExc_TypeError,
5919 "configuration names must be strings or integers");
5920 return 0;
5921}
5922
5923
5924#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5925static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005926#ifdef _PC_ABI_AIO_XFER_MAX
5927 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5928#endif
5929#ifdef _PC_ABI_ASYNC_IO
5930 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5931#endif
Fred Drakec9680921999-12-13 16:37:25 +00005932#ifdef _PC_ASYNC_IO
5933 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5934#endif
5935#ifdef _PC_CHOWN_RESTRICTED
5936 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5937#endif
5938#ifdef _PC_FILESIZEBITS
5939 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5940#endif
5941#ifdef _PC_LAST
5942 {"PC_LAST", _PC_LAST},
5943#endif
5944#ifdef _PC_LINK_MAX
5945 {"PC_LINK_MAX", _PC_LINK_MAX},
5946#endif
5947#ifdef _PC_MAX_CANON
5948 {"PC_MAX_CANON", _PC_MAX_CANON},
5949#endif
5950#ifdef _PC_MAX_INPUT
5951 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5952#endif
5953#ifdef _PC_NAME_MAX
5954 {"PC_NAME_MAX", _PC_NAME_MAX},
5955#endif
5956#ifdef _PC_NO_TRUNC
5957 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5958#endif
5959#ifdef _PC_PATH_MAX
5960 {"PC_PATH_MAX", _PC_PATH_MAX},
5961#endif
5962#ifdef _PC_PIPE_BUF
5963 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5964#endif
5965#ifdef _PC_PRIO_IO
5966 {"PC_PRIO_IO", _PC_PRIO_IO},
5967#endif
5968#ifdef _PC_SOCK_MAXBUF
5969 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5970#endif
5971#ifdef _PC_SYNC_IO
5972 {"PC_SYNC_IO", _PC_SYNC_IO},
5973#endif
5974#ifdef _PC_VDISABLE
5975 {"PC_VDISABLE", _PC_VDISABLE},
5976#endif
5977};
5978
Fred Drakec9680921999-12-13 16:37:25 +00005979static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005980conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005981{
5982 return conv_confname(arg, valuep, posix_constants_pathconf,
5983 sizeof(posix_constants_pathconf)
5984 / sizeof(struct constdef));
5985}
5986#endif
5987
5988#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005989PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005990"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005991Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005992If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005993
5994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005995posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005996{
5997 PyObject *result = NULL;
5998 int name, fd;
5999
Fred Drake12c6e2d1999-12-14 21:25:03 +00006000 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6001 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006002 long limit;
6003
6004 errno = 0;
6005 limit = fpathconf(fd, name);
6006 if (limit == -1 && errno != 0)
6007 posix_error();
6008 else
6009 result = PyInt_FromLong(limit);
6010 }
6011 return result;
6012}
6013#endif
6014
6015
6016#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006017PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006018"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006019Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006020If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006021
6022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006023posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006024{
6025 PyObject *result = NULL;
6026 int name;
6027 char *path;
6028
6029 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6030 conv_path_confname, &name)) {
6031 long limit;
6032
6033 errno = 0;
6034 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006035 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006036 if (errno == EINVAL)
6037 /* could be a path or name problem */
6038 posix_error();
6039 else
6040 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006041 }
Fred Drakec9680921999-12-13 16:37:25 +00006042 else
6043 result = PyInt_FromLong(limit);
6044 }
6045 return result;
6046}
6047#endif
6048
6049#ifdef HAVE_CONFSTR
6050static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006051#ifdef _CS_ARCHITECTURE
6052 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6053#endif
6054#ifdef _CS_HOSTNAME
6055 {"CS_HOSTNAME", _CS_HOSTNAME},
6056#endif
6057#ifdef _CS_HW_PROVIDER
6058 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6059#endif
6060#ifdef _CS_HW_SERIAL
6061 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6062#endif
6063#ifdef _CS_INITTAB_NAME
6064 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6065#endif
Fred Drakec9680921999-12-13 16:37:25 +00006066#ifdef _CS_LFS64_CFLAGS
6067 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6068#endif
6069#ifdef _CS_LFS64_LDFLAGS
6070 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6071#endif
6072#ifdef _CS_LFS64_LIBS
6073 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6074#endif
6075#ifdef _CS_LFS64_LINTFLAGS
6076 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6077#endif
6078#ifdef _CS_LFS_CFLAGS
6079 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6080#endif
6081#ifdef _CS_LFS_LDFLAGS
6082 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6083#endif
6084#ifdef _CS_LFS_LIBS
6085 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6086#endif
6087#ifdef _CS_LFS_LINTFLAGS
6088 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6089#endif
Fred Draked86ed291999-12-15 15:34:33 +00006090#ifdef _CS_MACHINE
6091 {"CS_MACHINE", _CS_MACHINE},
6092#endif
Fred Drakec9680921999-12-13 16:37:25 +00006093#ifdef _CS_PATH
6094 {"CS_PATH", _CS_PATH},
6095#endif
Fred Draked86ed291999-12-15 15:34:33 +00006096#ifdef _CS_RELEASE
6097 {"CS_RELEASE", _CS_RELEASE},
6098#endif
6099#ifdef _CS_SRPC_DOMAIN
6100 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6101#endif
6102#ifdef _CS_SYSNAME
6103 {"CS_SYSNAME", _CS_SYSNAME},
6104#endif
6105#ifdef _CS_VERSION
6106 {"CS_VERSION", _CS_VERSION},
6107#endif
Fred Drakec9680921999-12-13 16:37:25 +00006108#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6109 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6110#endif
6111#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6112 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6113#endif
6114#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6115 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6116#endif
6117#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6118 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6119#endif
6120#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6121 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6122#endif
6123#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6124 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6125#endif
6126#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6127 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6128#endif
6129#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6130 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6131#endif
6132#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6133 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6134#endif
6135#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6136 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6137#endif
6138#ifdef _CS_XBS5_LP64_OFF64_LIBS
6139 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6140#endif
6141#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6142 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6143#endif
6144#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6145 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6146#endif
6147#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6148 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6149#endif
6150#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6151 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6152#endif
6153#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6154 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6155#endif
Fred Draked86ed291999-12-15 15:34:33 +00006156#ifdef _MIPS_CS_AVAIL_PROCESSORS
6157 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6158#endif
6159#ifdef _MIPS_CS_BASE
6160 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6161#endif
6162#ifdef _MIPS_CS_HOSTID
6163 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6164#endif
6165#ifdef _MIPS_CS_HW_NAME
6166 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6167#endif
6168#ifdef _MIPS_CS_NUM_PROCESSORS
6169 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6170#endif
6171#ifdef _MIPS_CS_OSREL_MAJ
6172 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6173#endif
6174#ifdef _MIPS_CS_OSREL_MIN
6175 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6176#endif
6177#ifdef _MIPS_CS_OSREL_PATCH
6178 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6179#endif
6180#ifdef _MIPS_CS_OS_NAME
6181 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6182#endif
6183#ifdef _MIPS_CS_OS_PROVIDER
6184 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6185#endif
6186#ifdef _MIPS_CS_PROCESSORS
6187 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6188#endif
6189#ifdef _MIPS_CS_SERIAL
6190 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6191#endif
6192#ifdef _MIPS_CS_VENDOR
6193 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6194#endif
Fred Drakec9680921999-12-13 16:37:25 +00006195};
6196
6197static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006198conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006199{
6200 return conv_confname(arg, valuep, posix_constants_confstr,
6201 sizeof(posix_constants_confstr)
6202 / sizeof(struct constdef));
6203}
6204
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006205PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006206"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006207Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006208
6209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006210posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006211{
6212 PyObject *result = NULL;
6213 int name;
6214 char buffer[64];
6215
6216 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6217 int len = confstr(name, buffer, sizeof(buffer));
6218
Fred Drakec9680921999-12-13 16:37:25 +00006219 errno = 0;
6220 if (len == 0) {
6221 if (errno != 0)
6222 posix_error();
6223 else
6224 result = PyString_FromString("");
6225 }
6226 else {
6227 if (len >= sizeof(buffer)) {
6228 result = PyString_FromStringAndSize(NULL, len);
6229 if (result != NULL)
6230 confstr(name, PyString_AS_STRING(result), len+1);
6231 }
6232 else
6233 result = PyString_FromString(buffer);
6234 }
6235 }
6236 return result;
6237}
6238#endif
6239
6240
6241#ifdef HAVE_SYSCONF
6242static struct constdef posix_constants_sysconf[] = {
6243#ifdef _SC_2_CHAR_TERM
6244 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6245#endif
6246#ifdef _SC_2_C_BIND
6247 {"SC_2_C_BIND", _SC_2_C_BIND},
6248#endif
6249#ifdef _SC_2_C_DEV
6250 {"SC_2_C_DEV", _SC_2_C_DEV},
6251#endif
6252#ifdef _SC_2_C_VERSION
6253 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6254#endif
6255#ifdef _SC_2_FORT_DEV
6256 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6257#endif
6258#ifdef _SC_2_FORT_RUN
6259 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6260#endif
6261#ifdef _SC_2_LOCALEDEF
6262 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6263#endif
6264#ifdef _SC_2_SW_DEV
6265 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6266#endif
6267#ifdef _SC_2_UPE
6268 {"SC_2_UPE", _SC_2_UPE},
6269#endif
6270#ifdef _SC_2_VERSION
6271 {"SC_2_VERSION", _SC_2_VERSION},
6272#endif
Fred Draked86ed291999-12-15 15:34:33 +00006273#ifdef _SC_ABI_ASYNCHRONOUS_IO
6274 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6275#endif
6276#ifdef _SC_ACL
6277 {"SC_ACL", _SC_ACL},
6278#endif
Fred Drakec9680921999-12-13 16:37:25 +00006279#ifdef _SC_AIO_LISTIO_MAX
6280 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6281#endif
Fred Drakec9680921999-12-13 16:37:25 +00006282#ifdef _SC_AIO_MAX
6283 {"SC_AIO_MAX", _SC_AIO_MAX},
6284#endif
6285#ifdef _SC_AIO_PRIO_DELTA_MAX
6286 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6287#endif
6288#ifdef _SC_ARG_MAX
6289 {"SC_ARG_MAX", _SC_ARG_MAX},
6290#endif
6291#ifdef _SC_ASYNCHRONOUS_IO
6292 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6293#endif
6294#ifdef _SC_ATEXIT_MAX
6295 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6296#endif
Fred Draked86ed291999-12-15 15:34:33 +00006297#ifdef _SC_AUDIT
6298 {"SC_AUDIT", _SC_AUDIT},
6299#endif
Fred Drakec9680921999-12-13 16:37:25 +00006300#ifdef _SC_AVPHYS_PAGES
6301 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6302#endif
6303#ifdef _SC_BC_BASE_MAX
6304 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6305#endif
6306#ifdef _SC_BC_DIM_MAX
6307 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6308#endif
6309#ifdef _SC_BC_SCALE_MAX
6310 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6311#endif
6312#ifdef _SC_BC_STRING_MAX
6313 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6314#endif
Fred Draked86ed291999-12-15 15:34:33 +00006315#ifdef _SC_CAP
6316 {"SC_CAP", _SC_CAP},
6317#endif
Fred Drakec9680921999-12-13 16:37:25 +00006318#ifdef _SC_CHARCLASS_NAME_MAX
6319 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6320#endif
6321#ifdef _SC_CHAR_BIT
6322 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6323#endif
6324#ifdef _SC_CHAR_MAX
6325 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6326#endif
6327#ifdef _SC_CHAR_MIN
6328 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6329#endif
6330#ifdef _SC_CHILD_MAX
6331 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6332#endif
6333#ifdef _SC_CLK_TCK
6334 {"SC_CLK_TCK", _SC_CLK_TCK},
6335#endif
6336#ifdef _SC_COHER_BLKSZ
6337 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6338#endif
6339#ifdef _SC_COLL_WEIGHTS_MAX
6340 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6341#endif
6342#ifdef _SC_DCACHE_ASSOC
6343 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6344#endif
6345#ifdef _SC_DCACHE_BLKSZ
6346 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6347#endif
6348#ifdef _SC_DCACHE_LINESZ
6349 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6350#endif
6351#ifdef _SC_DCACHE_SZ
6352 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6353#endif
6354#ifdef _SC_DCACHE_TBLKSZ
6355 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6356#endif
6357#ifdef _SC_DELAYTIMER_MAX
6358 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6359#endif
6360#ifdef _SC_EQUIV_CLASS_MAX
6361 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6362#endif
6363#ifdef _SC_EXPR_NEST_MAX
6364 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6365#endif
6366#ifdef _SC_FSYNC
6367 {"SC_FSYNC", _SC_FSYNC},
6368#endif
6369#ifdef _SC_GETGR_R_SIZE_MAX
6370 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6371#endif
6372#ifdef _SC_GETPW_R_SIZE_MAX
6373 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6374#endif
6375#ifdef _SC_ICACHE_ASSOC
6376 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6377#endif
6378#ifdef _SC_ICACHE_BLKSZ
6379 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6380#endif
6381#ifdef _SC_ICACHE_LINESZ
6382 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6383#endif
6384#ifdef _SC_ICACHE_SZ
6385 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6386#endif
Fred Draked86ed291999-12-15 15:34:33 +00006387#ifdef _SC_INF
6388 {"SC_INF", _SC_INF},
6389#endif
Fred Drakec9680921999-12-13 16:37:25 +00006390#ifdef _SC_INT_MAX
6391 {"SC_INT_MAX", _SC_INT_MAX},
6392#endif
6393#ifdef _SC_INT_MIN
6394 {"SC_INT_MIN", _SC_INT_MIN},
6395#endif
6396#ifdef _SC_IOV_MAX
6397 {"SC_IOV_MAX", _SC_IOV_MAX},
6398#endif
Fred Draked86ed291999-12-15 15:34:33 +00006399#ifdef _SC_IP_SECOPTS
6400 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6401#endif
Fred Drakec9680921999-12-13 16:37:25 +00006402#ifdef _SC_JOB_CONTROL
6403 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6404#endif
Fred Draked86ed291999-12-15 15:34:33 +00006405#ifdef _SC_KERN_POINTERS
6406 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6407#endif
6408#ifdef _SC_KERN_SIM
6409 {"SC_KERN_SIM", _SC_KERN_SIM},
6410#endif
Fred Drakec9680921999-12-13 16:37:25 +00006411#ifdef _SC_LINE_MAX
6412 {"SC_LINE_MAX", _SC_LINE_MAX},
6413#endif
6414#ifdef _SC_LOGIN_NAME_MAX
6415 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6416#endif
6417#ifdef _SC_LOGNAME_MAX
6418 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6419#endif
6420#ifdef _SC_LONG_BIT
6421 {"SC_LONG_BIT", _SC_LONG_BIT},
6422#endif
Fred Draked86ed291999-12-15 15:34:33 +00006423#ifdef _SC_MAC
6424 {"SC_MAC", _SC_MAC},
6425#endif
Fred Drakec9680921999-12-13 16:37:25 +00006426#ifdef _SC_MAPPED_FILES
6427 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6428#endif
6429#ifdef _SC_MAXPID
6430 {"SC_MAXPID", _SC_MAXPID},
6431#endif
6432#ifdef _SC_MB_LEN_MAX
6433 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6434#endif
6435#ifdef _SC_MEMLOCK
6436 {"SC_MEMLOCK", _SC_MEMLOCK},
6437#endif
6438#ifdef _SC_MEMLOCK_RANGE
6439 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6440#endif
6441#ifdef _SC_MEMORY_PROTECTION
6442 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6443#endif
6444#ifdef _SC_MESSAGE_PASSING
6445 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6446#endif
Fred Draked86ed291999-12-15 15:34:33 +00006447#ifdef _SC_MMAP_FIXED_ALIGNMENT
6448 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6449#endif
Fred Drakec9680921999-12-13 16:37:25 +00006450#ifdef _SC_MQ_OPEN_MAX
6451 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6452#endif
6453#ifdef _SC_MQ_PRIO_MAX
6454 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6455#endif
Fred Draked86ed291999-12-15 15:34:33 +00006456#ifdef _SC_NACLS_MAX
6457 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6458#endif
Fred Drakec9680921999-12-13 16:37:25 +00006459#ifdef _SC_NGROUPS_MAX
6460 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6461#endif
6462#ifdef _SC_NL_ARGMAX
6463 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6464#endif
6465#ifdef _SC_NL_LANGMAX
6466 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6467#endif
6468#ifdef _SC_NL_MSGMAX
6469 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6470#endif
6471#ifdef _SC_NL_NMAX
6472 {"SC_NL_NMAX", _SC_NL_NMAX},
6473#endif
6474#ifdef _SC_NL_SETMAX
6475 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6476#endif
6477#ifdef _SC_NL_TEXTMAX
6478 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6479#endif
6480#ifdef _SC_NPROCESSORS_CONF
6481 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6482#endif
6483#ifdef _SC_NPROCESSORS_ONLN
6484 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6485#endif
Fred Draked86ed291999-12-15 15:34:33 +00006486#ifdef _SC_NPROC_CONF
6487 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6488#endif
6489#ifdef _SC_NPROC_ONLN
6490 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6491#endif
Fred Drakec9680921999-12-13 16:37:25 +00006492#ifdef _SC_NZERO
6493 {"SC_NZERO", _SC_NZERO},
6494#endif
6495#ifdef _SC_OPEN_MAX
6496 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6497#endif
6498#ifdef _SC_PAGESIZE
6499 {"SC_PAGESIZE", _SC_PAGESIZE},
6500#endif
6501#ifdef _SC_PAGE_SIZE
6502 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6503#endif
6504#ifdef _SC_PASS_MAX
6505 {"SC_PASS_MAX", _SC_PASS_MAX},
6506#endif
6507#ifdef _SC_PHYS_PAGES
6508 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6509#endif
6510#ifdef _SC_PII
6511 {"SC_PII", _SC_PII},
6512#endif
6513#ifdef _SC_PII_INTERNET
6514 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6515#endif
6516#ifdef _SC_PII_INTERNET_DGRAM
6517 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6518#endif
6519#ifdef _SC_PII_INTERNET_STREAM
6520 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6521#endif
6522#ifdef _SC_PII_OSI
6523 {"SC_PII_OSI", _SC_PII_OSI},
6524#endif
6525#ifdef _SC_PII_OSI_CLTS
6526 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6527#endif
6528#ifdef _SC_PII_OSI_COTS
6529 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6530#endif
6531#ifdef _SC_PII_OSI_M
6532 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6533#endif
6534#ifdef _SC_PII_SOCKET
6535 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6536#endif
6537#ifdef _SC_PII_XTI
6538 {"SC_PII_XTI", _SC_PII_XTI},
6539#endif
6540#ifdef _SC_POLL
6541 {"SC_POLL", _SC_POLL},
6542#endif
6543#ifdef _SC_PRIORITIZED_IO
6544 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6545#endif
6546#ifdef _SC_PRIORITY_SCHEDULING
6547 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6548#endif
6549#ifdef _SC_REALTIME_SIGNALS
6550 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6551#endif
6552#ifdef _SC_RE_DUP_MAX
6553 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6554#endif
6555#ifdef _SC_RTSIG_MAX
6556 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6557#endif
6558#ifdef _SC_SAVED_IDS
6559 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6560#endif
6561#ifdef _SC_SCHAR_MAX
6562 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6563#endif
6564#ifdef _SC_SCHAR_MIN
6565 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6566#endif
6567#ifdef _SC_SELECT
6568 {"SC_SELECT", _SC_SELECT},
6569#endif
6570#ifdef _SC_SEMAPHORES
6571 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6572#endif
6573#ifdef _SC_SEM_NSEMS_MAX
6574 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6575#endif
6576#ifdef _SC_SEM_VALUE_MAX
6577 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6578#endif
6579#ifdef _SC_SHARED_MEMORY_OBJECTS
6580 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6581#endif
6582#ifdef _SC_SHRT_MAX
6583 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6584#endif
6585#ifdef _SC_SHRT_MIN
6586 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6587#endif
6588#ifdef _SC_SIGQUEUE_MAX
6589 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6590#endif
6591#ifdef _SC_SIGRT_MAX
6592 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6593#endif
6594#ifdef _SC_SIGRT_MIN
6595 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6596#endif
Fred Draked86ed291999-12-15 15:34:33 +00006597#ifdef _SC_SOFTPOWER
6598 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6599#endif
Fred Drakec9680921999-12-13 16:37:25 +00006600#ifdef _SC_SPLIT_CACHE
6601 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6602#endif
6603#ifdef _SC_SSIZE_MAX
6604 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6605#endif
6606#ifdef _SC_STACK_PROT
6607 {"SC_STACK_PROT", _SC_STACK_PROT},
6608#endif
6609#ifdef _SC_STREAM_MAX
6610 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6611#endif
6612#ifdef _SC_SYNCHRONIZED_IO
6613 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6614#endif
6615#ifdef _SC_THREADS
6616 {"SC_THREADS", _SC_THREADS},
6617#endif
6618#ifdef _SC_THREAD_ATTR_STACKADDR
6619 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6620#endif
6621#ifdef _SC_THREAD_ATTR_STACKSIZE
6622 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6623#endif
6624#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6625 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6626#endif
6627#ifdef _SC_THREAD_KEYS_MAX
6628 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6629#endif
6630#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6631 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6632#endif
6633#ifdef _SC_THREAD_PRIO_INHERIT
6634 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6635#endif
6636#ifdef _SC_THREAD_PRIO_PROTECT
6637 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6638#endif
6639#ifdef _SC_THREAD_PROCESS_SHARED
6640 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6641#endif
6642#ifdef _SC_THREAD_SAFE_FUNCTIONS
6643 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6644#endif
6645#ifdef _SC_THREAD_STACK_MIN
6646 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6647#endif
6648#ifdef _SC_THREAD_THREADS_MAX
6649 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6650#endif
6651#ifdef _SC_TIMERS
6652 {"SC_TIMERS", _SC_TIMERS},
6653#endif
6654#ifdef _SC_TIMER_MAX
6655 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6656#endif
6657#ifdef _SC_TTY_NAME_MAX
6658 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6659#endif
6660#ifdef _SC_TZNAME_MAX
6661 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6662#endif
6663#ifdef _SC_T_IOV_MAX
6664 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6665#endif
6666#ifdef _SC_UCHAR_MAX
6667 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6668#endif
6669#ifdef _SC_UINT_MAX
6670 {"SC_UINT_MAX", _SC_UINT_MAX},
6671#endif
6672#ifdef _SC_UIO_MAXIOV
6673 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6674#endif
6675#ifdef _SC_ULONG_MAX
6676 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6677#endif
6678#ifdef _SC_USHRT_MAX
6679 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6680#endif
6681#ifdef _SC_VERSION
6682 {"SC_VERSION", _SC_VERSION},
6683#endif
6684#ifdef _SC_WORD_BIT
6685 {"SC_WORD_BIT", _SC_WORD_BIT},
6686#endif
6687#ifdef _SC_XBS5_ILP32_OFF32
6688 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6689#endif
6690#ifdef _SC_XBS5_ILP32_OFFBIG
6691 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6692#endif
6693#ifdef _SC_XBS5_LP64_OFF64
6694 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6695#endif
6696#ifdef _SC_XBS5_LPBIG_OFFBIG
6697 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6698#endif
6699#ifdef _SC_XOPEN_CRYPT
6700 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6701#endif
6702#ifdef _SC_XOPEN_ENH_I18N
6703 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6704#endif
6705#ifdef _SC_XOPEN_LEGACY
6706 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6707#endif
6708#ifdef _SC_XOPEN_REALTIME
6709 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6710#endif
6711#ifdef _SC_XOPEN_REALTIME_THREADS
6712 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6713#endif
6714#ifdef _SC_XOPEN_SHM
6715 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6716#endif
6717#ifdef _SC_XOPEN_UNIX
6718 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6719#endif
6720#ifdef _SC_XOPEN_VERSION
6721 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6722#endif
6723#ifdef _SC_XOPEN_XCU_VERSION
6724 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6725#endif
6726#ifdef _SC_XOPEN_XPG2
6727 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6728#endif
6729#ifdef _SC_XOPEN_XPG3
6730 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6731#endif
6732#ifdef _SC_XOPEN_XPG4
6733 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6734#endif
6735};
6736
6737static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006738conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006739{
6740 return conv_confname(arg, valuep, posix_constants_sysconf,
6741 sizeof(posix_constants_sysconf)
6742 / sizeof(struct constdef));
6743}
6744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006745PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006746"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006747Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006748
6749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006750posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006751{
6752 PyObject *result = NULL;
6753 int name;
6754
6755 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6756 int value;
6757
6758 errno = 0;
6759 value = sysconf(name);
6760 if (value == -1 && errno != 0)
6761 posix_error();
6762 else
6763 result = PyInt_FromLong(value);
6764 }
6765 return result;
6766}
6767#endif
6768
6769
Fred Drakebec628d1999-12-15 18:31:10 +00006770/* This code is used to ensure that the tables of configuration value names
6771 * are in sorted order as required by conv_confname(), and also to build the
6772 * the exported dictionaries that are used to publish information about the
6773 * names available on the host platform.
6774 *
6775 * Sorting the table at runtime ensures that the table is properly ordered
6776 * when used, even for platforms we're not able to test on. It also makes
6777 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006778 */
Fred Drakebec628d1999-12-15 18:31:10 +00006779
6780static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006781cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006782{
6783 const struct constdef *c1 =
6784 (const struct constdef *) v1;
6785 const struct constdef *c2 =
6786 (const struct constdef *) v2;
6787
6788 return strcmp(c1->name, c2->name);
6789}
6790
6791static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006792setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006793 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006794{
Fred Drakebec628d1999-12-15 18:31:10 +00006795 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006796 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006797
6798 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6799 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006800 if (d == NULL)
6801 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006802
Barry Warsaw3155db32000-04-13 15:20:40 +00006803 for (i=0; i < tablesize; ++i) {
6804 PyObject *o = PyInt_FromLong(table[i].value);
6805 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6806 Py_XDECREF(o);
6807 Py_DECREF(d);
6808 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006809 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006810 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006811 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006812 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006813}
6814
Fred Drakebec628d1999-12-15 18:31:10 +00006815/* Return -1 on failure, 0 on success. */
6816static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006817setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006818{
6819#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006820 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006821 sizeof(posix_constants_pathconf)
6822 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006823 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006824 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006825#endif
6826#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006827 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006828 sizeof(posix_constants_confstr)
6829 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006830 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006831 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006832#endif
6833#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006834 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006835 sizeof(posix_constants_sysconf)
6836 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006837 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006838 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006839#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006840 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006841}
Fred Draked86ed291999-12-15 15:34:33 +00006842
6843
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006844PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006845"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006846Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006847in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006848
6849static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006850posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006851{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006852 abort();
6853 /*NOTREACHED*/
6854 Py_FatalError("abort() called from Python code didn't abort!");
6855 return NULL;
6856}
Fred Drakebec628d1999-12-15 18:31:10 +00006857
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006858#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006859PyDoc_STRVAR(win32_startfile__doc__,
6860"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006861\n\
6862This acts like double-clicking the file in Explorer, or giving the file\n\
6863name as an argument to the DOS \"start\" command: the file is opened\n\
6864with whatever application (if any) its extension is associated.\n\
6865\n\
6866startfile returns as soon as the associated application is launched.\n\
6867There is no option to wait for the application to close, and no way\n\
6868to retrieve the application's exit status.\n\
6869\n\
6870The filepath is relative to the current directory. If you want to use\n\
6871an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006872the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006873
6874static PyObject *
6875win32_startfile(PyObject *self, PyObject *args)
6876{
6877 char *filepath;
6878 HINSTANCE rc;
6879 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6880 return NULL;
6881 Py_BEGIN_ALLOW_THREADS
6882 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6883 Py_END_ALLOW_THREADS
6884 if (rc <= (HINSTANCE)32)
6885 return win32_error("startfile", filepath);
6886 Py_INCREF(Py_None);
6887 return Py_None;
6888}
6889#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006890
Martin v. Löwis438b5342002-12-27 10:16:42 +00006891#ifdef HAVE_GETLOADAVG
6892PyDoc_STRVAR(posix_getloadavg__doc__,
6893"getloadavg() -> (float, float, float)\n\n\
6894Return the number of processes in the system run queue averaged over\n\
6895the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6896was unobtainable");
6897
6898static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006899posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006900{
6901 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006902 if (getloadavg(loadavg, 3)!=3) {
6903 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6904 return NULL;
6905 } else
6906 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6907}
6908#endif
6909
6910
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006911static PyMethodDef posix_methods[] = {
6912 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6913#ifdef HAVE_TTYNAME
6914 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6915#endif
6916 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6917 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006918#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006919 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006920#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006921#ifdef HAVE_LCHOWN
6922 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6923#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006924#ifdef HAVE_CHROOT
6925 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6926#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006927#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006928 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006929#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006930#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006931 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00006932#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00006933 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006934#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00006935#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006936#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006937 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006938#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006939 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6940 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6941 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006942#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006943 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006944#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006945#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006946 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006947#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006948 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6949 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6950 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006951 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006952#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006953 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006954#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006955#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006956 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006957#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006958 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006959#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006960 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006961#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006962 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6963 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6964 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006965#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006966 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006967#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006968 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006969#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006970 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6971 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006972#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006973#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006974 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6975 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006976#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006977#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006978 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006979#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006980#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006981 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006982#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006983#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006984 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006985#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006986#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006987 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006988#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006989#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006990 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006991#endif /* HAVE_GETEGID */
6992#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006993 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006994#endif /* HAVE_GETEUID */
6995#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006996 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006997#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006998#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006999 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007000#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007001 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007002#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007003 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007004#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007005#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007006 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007007#endif /* HAVE_GETPPID */
7008#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007009 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007010#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007011#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007012 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007013#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007014#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007015 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007016#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007017#ifdef HAVE_KILLPG
7018 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7019#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007020#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007021 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007022#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007023#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007024 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007025#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007026 {"popen2", win32_popen2, METH_VARARGS},
7027 {"popen3", win32_popen3, METH_VARARGS},
7028 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007029 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007030#else
7031#if defined(PYOS_OS2) && defined(PYCC_GCC)
7032 {"popen2", os2emx_popen2, METH_VARARGS},
7033 {"popen3", os2emx_popen3, METH_VARARGS},
7034 {"popen4", os2emx_popen4, METH_VARARGS},
7035#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007036#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007037#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007038#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007039 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007040#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007041#ifdef HAVE_SETEUID
7042 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7043#endif /* HAVE_SETEUID */
7044#ifdef HAVE_SETEGID
7045 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7046#endif /* HAVE_SETEGID */
7047#ifdef HAVE_SETREUID
7048 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7049#endif /* HAVE_SETREUID */
7050#ifdef HAVE_SETREGID
7051 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7052#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007053#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007054 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007055#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007056#ifdef HAVE_SETGROUPS
7057 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7058#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007059#ifdef HAVE_GETPGID
7060 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7061#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007062#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007063 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007064#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007065#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007066 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007067#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007068#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007069 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007070#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007071#ifdef HAVE_GETSID
7072 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7073#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007074#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007075 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007076#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007077#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007078 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007079#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007080#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007081 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007082#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007083#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007084 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007085#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007086 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7087 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7088 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7089 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7090 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7091 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7092 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7093 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7094 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007095 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007096#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007097 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007098#endif
7099#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007100 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007101#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007102#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007103 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7104#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007105#ifdef HAVE_DEVICE_MACROS
7106 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7107 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7108 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7109#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007110#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007111 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007112#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007113#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007114 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007115#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007116#ifdef HAVE_UNSETENV
7117 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7118#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007119#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007120 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007121#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007122#ifdef HAVE_FCHDIR
7123 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7124#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007125#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007126 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007127#endif
7128#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007129 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007130#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007131#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007132#ifdef WCOREDUMP
7133 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7134#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007135#ifdef WIFCONTINUED
7136 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7137#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007138#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007139 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007140#endif /* WIFSTOPPED */
7141#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007142 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007143#endif /* WIFSIGNALED */
7144#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007145 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007146#endif /* WIFEXITED */
7147#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007148 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007149#endif /* WEXITSTATUS */
7150#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007151 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007152#endif /* WTERMSIG */
7153#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007154 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007155#endif /* WSTOPSIG */
7156#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007157#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007158 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007159#endif
7160#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007161 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007162#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007163#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007164 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007165#endif
7166#ifdef HAVE_TEMPNAM
7167 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7168#endif
7169#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007170 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007171#endif
Fred Drakec9680921999-12-13 16:37:25 +00007172#ifdef HAVE_CONFSTR
7173 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7174#endif
7175#ifdef HAVE_SYSCONF
7176 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7177#endif
7178#ifdef HAVE_FPATHCONF
7179 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7180#endif
7181#ifdef HAVE_PATHCONF
7182 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7183#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007184 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007185#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007186 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7187#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007188#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007189 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007190#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007191 {NULL, NULL} /* Sentinel */
7192};
7193
7194
Barry Warsaw4a342091996-12-19 23:50:02 +00007195static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007196ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007197{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007198 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007199}
7200
Guido van Rossumd48f2521997-12-05 22:19:34 +00007201#if defined(PYOS_OS2)
7202/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007203static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007204{
7205 APIRET rc;
7206 ULONG values[QSV_MAX+1];
7207 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007208 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007209
7210 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007211 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007212 Py_END_ALLOW_THREADS
7213
7214 if (rc != NO_ERROR) {
7215 os2_error(rc);
7216 return -1;
7217 }
7218
Fred Drake4d1e64b2002-04-15 19:40:07 +00007219 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7220 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7221 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7222 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7223 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7224 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7225 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007226
7227 switch (values[QSV_VERSION_MINOR]) {
7228 case 0: ver = "2.00"; break;
7229 case 10: ver = "2.10"; break;
7230 case 11: ver = "2.11"; break;
7231 case 30: ver = "3.00"; break;
7232 case 40: ver = "4.00"; break;
7233 case 50: ver = "5.00"; break;
7234 default:
Tim Peters885d4572001-11-28 20:27:42 +00007235 PyOS_snprintf(tmp, sizeof(tmp),
7236 "%d-%d", values[QSV_VERSION_MAJOR],
7237 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007238 ver = &tmp[0];
7239 }
7240
7241 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007242 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007243 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007244
7245 /* Add Indicator of Which Drive was Used to Boot the System */
7246 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7247 tmp[1] = ':';
7248 tmp[2] = '\0';
7249
Fred Drake4d1e64b2002-04-15 19:40:07 +00007250 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007251}
7252#endif
7253
Barry Warsaw4a342091996-12-19 23:50:02 +00007254static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007255all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007256{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007257#ifdef F_OK
7258 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007259#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007260#ifdef R_OK
7261 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007262#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007263#ifdef W_OK
7264 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007265#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007266#ifdef X_OK
7267 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007268#endif
Fred Drakec9680921999-12-13 16:37:25 +00007269#ifdef NGROUPS_MAX
7270 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7271#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007272#ifdef TMP_MAX
7273 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7274#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007275#ifdef WCONTINUED
7276 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7277#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007278#ifdef WNOHANG
7279 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007280#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007281#ifdef WUNTRACED
7282 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7283#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007284#ifdef O_RDONLY
7285 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7286#endif
7287#ifdef O_WRONLY
7288 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7289#endif
7290#ifdef O_RDWR
7291 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7292#endif
7293#ifdef O_NDELAY
7294 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7295#endif
7296#ifdef O_NONBLOCK
7297 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7298#endif
7299#ifdef O_APPEND
7300 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7301#endif
7302#ifdef O_DSYNC
7303 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7304#endif
7305#ifdef O_RSYNC
7306 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7307#endif
7308#ifdef O_SYNC
7309 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7310#endif
7311#ifdef O_NOCTTY
7312 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7313#endif
7314#ifdef O_CREAT
7315 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7316#endif
7317#ifdef O_EXCL
7318 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7319#endif
7320#ifdef O_TRUNC
7321 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7322#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007323#ifdef O_BINARY
7324 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7325#endif
7326#ifdef O_TEXT
7327 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7328#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007329#ifdef O_LARGEFILE
7330 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7331#endif
7332
Tim Peters5aa91602002-01-30 05:46:57 +00007333/* MS Windows */
7334#ifdef O_NOINHERIT
7335 /* Don't inherit in child processes. */
7336 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7337#endif
7338#ifdef _O_SHORT_LIVED
7339 /* Optimize for short life (keep in memory). */
7340 /* MS forgot to define this one with a non-underscore form too. */
7341 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7342#endif
7343#ifdef O_TEMPORARY
7344 /* Automatically delete when last handle is closed. */
7345 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7346#endif
7347#ifdef O_RANDOM
7348 /* Optimize for random access. */
7349 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7350#endif
7351#ifdef O_SEQUENTIAL
7352 /* Optimize for sequential access. */
7353 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7354#endif
7355
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007356/* GNU extensions. */
7357#ifdef O_DIRECT
7358 /* Direct disk access. */
7359 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7360#endif
7361#ifdef O_DIRECTORY
7362 /* Must be a directory. */
7363 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7364#endif
7365#ifdef O_NOFOLLOW
7366 /* Do not follow links. */
7367 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7368#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007369
Barry Warsaw5676bd12003-01-07 20:57:09 +00007370 /* These come from sysexits.h */
7371#ifdef EX_OK
7372 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007373#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007374#ifdef EX_USAGE
7375 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007376#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007377#ifdef EX_DATAERR
7378 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007379#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007380#ifdef EX_NOINPUT
7381 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007382#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007383#ifdef EX_NOUSER
7384 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007385#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007386#ifdef EX_NOHOST
7387 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007388#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007389#ifdef EX_UNAVAILABLE
7390 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007391#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007392#ifdef EX_SOFTWARE
7393 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007394#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007395#ifdef EX_OSERR
7396 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007397#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007398#ifdef EX_OSFILE
7399 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007400#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007401#ifdef EX_CANTCREAT
7402 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007403#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007404#ifdef EX_IOERR
7405 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007406#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007407#ifdef EX_TEMPFAIL
7408 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007409#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007410#ifdef EX_PROTOCOL
7411 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007412#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007413#ifdef EX_NOPERM
7414 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007415#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007416#ifdef EX_CONFIG
7417 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007418#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007419#ifdef EX_NOTFOUND
7420 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007421#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007422
Guido van Rossum246bc171999-02-01 23:54:31 +00007423#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007424#if defined(PYOS_OS2) && defined(PYCC_GCC)
7425 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7426 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7427 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7428 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7429 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7430 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7431 if (ins(d, "P_PM", (long)P_PM)) return -1;
7432 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7433 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7434 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7435 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7436 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7437 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7438 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7439 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7440 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7441 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7442 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7443 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7444 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7445#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007446 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7447 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7448 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7449 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7450 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007451#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007452#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007453
Guido van Rossumd48f2521997-12-05 22:19:34 +00007454#if defined(PYOS_OS2)
7455 if (insertvalues(d)) return -1;
7456#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007457 return 0;
7458}
7459
7460
Tim Peters5aa91602002-01-30 05:46:57 +00007461#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007462#define INITFUNC initnt
7463#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007464
7465#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007466#define INITFUNC initos2
7467#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007468
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007469#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007470#define INITFUNC initposix
7471#define MODNAME "posix"
7472#endif
7473
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007474PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007475INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007476{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007477 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007478
Fred Drake4d1e64b2002-04-15 19:40:07 +00007479 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007480 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007481 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007482
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007483 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007484 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007485 Py_XINCREF(v);
7486 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007487 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007488 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007489
Fred Drake4d1e64b2002-04-15 19:40:07 +00007490 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007491 return;
7492
Fred Drake4d1e64b2002-04-15 19:40:07 +00007493 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007494 return;
7495
Fred Drake4d1e64b2002-04-15 19:40:07 +00007496 Py_INCREF(PyExc_OSError);
7497 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007498
Guido van Rossumb3d39562000-01-31 18:41:26 +00007499#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007500 if (posix_putenv_garbage == NULL)
7501 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007502#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007503
Guido van Rossum14648392001-12-08 18:02:58 +00007504 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007505 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7506 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7507 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007508 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007509 structseq_new = StatResultType.tp_new;
7510 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007511 Py_INCREF((PyObject*) &StatResultType);
7512 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007513
Guido van Rossum14648392001-12-08 18:02:58 +00007514 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007515 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007516 Py_INCREF((PyObject*) &StatVFSResultType);
7517 PyModule_AddObject(m, "statvfs_result",
7518 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007519}